Commit Graph
34 Commits
Author SHA1 Message Date
lefarcenandGitHub 935034cc20 fix(diagnostics): desktop export delegates to daemon so run/AMR logs are captured (#4405)
The desktop "Export diagnostics" path rebuilt the support bundle in the
Electron main process and had to GUESS the daemon data dir from the sidecar
namespace layout (`<namespaceRoot>/data`). That guess is wrong whenever the
daemon's real RUNTIME_DATA_DIR differs: in tools-dev it is `<projectRoot>/.od`
(OD_DATA_DIR unset), and under any OD_DATA_DIR override it is elsewhere. The
exporter then swept the wrong `runs/` and `amr/opencode-home` trees and
silently dropped the per-run `events.jsonl` (which already records every agent
stderr chunk, tool call, and error) and the AMR OpenCode logs — the exact data
needed to explain a stuck/looping run that produced nothing.

The daemon already exposes a complete, correctly-pathed bundle at
`GET /api/diagnostics/export` (it knows its own RUNTIME_DATA_DIR and collects
run events, agent CLI logs, sidecar daemon/web/desktop logs incl. renderer.log,
and host crash reports). So delegate to it instead of duplicating the assembly:

- desktop: new electron-free `diagnostics-fetch.ts` fetches the daemon bundle;
  `diagnostics.ts` keeps only the save dialog + reveal and saves those bytes.
  Removes the data-dir guessing entirely (net -141 lines in diagnostics.ts).
- index.ts: share one `resolveDaemonBaseUrl(runtime, options)` (daemon URL →
  web URL → sidecar web discovery) across app-config menu actions and the
  diagnostics IPC, so the export targets the same daemon as everything else.
- daemon: emit a manifest warning when `runsDir` is set but no per-run event
  logs were found, so an empty bundle reads as "collection gap / persistence
  off" rather than "clean run with nothing to report".

Tests: desktop `fetchDiagnosticsBundle` hits the daemon export endpoint and
surfaces non-200 as an error; daemon export warns on an empty runs dir. Both
red before the change.
2026-06-16 09:26:50 +00:00
fbc5fe3458 fix(desktop): scope window-chrome spec matching to the main app window block (#4216)
* fix(desktop): scope window-chrome spec matching to the main app window block

The backgroundThrottling and autoHideMenuBar specs extracted the
BrowserWindow options with a non-greedy whole-source regex anchored on
title: "Open Design" / width: 1280. Since the packaged brand splash
window (createSplashWindow) shares both markers and appears earlier in
runtime.ts, the regex locked onto the splash block: the
backgroundThrottling spec failed (splash intentionally has no
backgroundThrottling: false) and the autoHideMenuBar spec passed only
coincidentally against the wrong window.

Split the source into per-constructor option blocks and select the main
app window by the marker pair unique to it (app title + preload),
asserting exactly one match so a future fourth window fails loudly
instead of being checked ambiguously.

https://claude.ai/code/session_016MqkcZLEz3NzgNKgU2ARLd

* test(desktop): anchor window-chrome selector on the unique main-window declaration

Adopt the clearer anchor from the upstream fix: select the main app
window by the `const window = new BrowserWindow({` declaration, which is
unique to it, instead of the indirect title + preload marker pair. Keep
the exactly-one-match assertion so a rename or a duplicate declaration
fails loudly rather than silently inspecting the wrong window.

https://claude.ai/code/session_016MqkcZLEz3NzgNKgU2ARLd

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-14 08:55:14 +00:00
Chris SeifertandGitHub a1742e2fa9 fix(desktop): recover the window when the renderer dies or a load fails (#4179)
* fix(desktop): recover the window when the renderer dies or a load fails

The main window's poll loader only calls loadURL when the discovered web
URL changes, so a renderer that dies after a successful load is never
reloaded. The render-process-gone handler only reported the crash to
analytics, and there was no did-fail-load handler, so a failed main-frame
load left the renderer parked on chrome-error:// (blank white) with no
retry. That is the blank window after minimizing and restoring the app:
the OS reclaims the backgrounded renderer or its connection drops, and
nothing brings it back.

Add a rendererFailed flag set by did-fail-load (ignoring -3 aborts) and by
a non-clean render-process-gone, and have the poll loop reload the current
URL while the flag is set, clearing it on a successful load. When the web
server is still unreachable, discovery returns null and the loop backs off
to its normal interval until it returns.

Verified in the running app: forcing the renderer to a refused port parks
it on chrome-error, then the next poll reloads it back to the mounted app.

* fix(desktop): keep a single poll loop when a renderer load fails mid-tick

markRendererFailed scheduled its own prompt retry, but a loadURL that rejects inside tick fires did-fail-load AND falls into tick's catch, so both queued a poll timer and the loop forked into two (multiplying on each repeated failure). Track whether a tick is in flight and have the failure handler only flip the rendererFailed flag while one is running, leaving tick as the sole rescheduler. An idle renderer death still reschedules promptly.

Adds a source-assertion regression test in the window-chrome.test.ts style, since the loop lives inside createDesktopRuntime and has no behavioral seam under vitest.

Addresses review feedback on #4179.
2026-06-13 12:49:32 +00:00
fancyandGitHub 7e3b8a3b32 Fix blank/clipped desktop PDF export by sizing the page to artifact content (#4067) (#4086)
* Fix blank/clipped desktop PDF export by sizing the page to artifact content (#4067)

The desktop PDF export wraps the artifact in a sandboxed-preview iframe
(sandbox="allow-scripts", no allow-same-origin) inside an overflow:hidden
wrapper. inferPageSize() measured the wrapper document, which is pinned to the
window viewport, so taller artifacts were clipped and content sitting below the
fold exported as a blank white page.

The wrapper can't read the cross-origin iframe, so the artifact now reports its
own content dimensions through the existing print-ready handshake. The parent
caches them as window.__odPrintSize (nonce + source checked, validated as a
positive finite size) and inferPageSize() prefers that over measuring the
wrapper, falling back to direct measurement for the daemon path that runs no
handshake. Purely additive: other export paths never set __odPrintSize and are
unchanged.

* Reject non-finite reported print sizes in the #4067 handshake guard

The __odPrintSize validation accepted any `typeof === 'number'` that was
`> 0`, so `Infinity` slipped through (`Infinity > 0` is true) despite the
guard's intent — and its comment — being "positive finite numbers". A
malformed `{ width: 756, height: Infinity }` then sized the desktop PDF
page to a Frankenstein 756x900 (reported width kept, non-finite height
dropped to 900) instead of falling back cleanly to direct measurement.

Tighten both the parent write guard (apps/web/src/runtime/exports.ts) and
the mirrored consumer guard (apps/desktop/src/main/pdf-export.ts) to
`Number.isFinite(x) && x > 0`, and add a desktop regression that feeds a
non-finite height and asserts the whole reported size is rejected.
2026-06-11 15:17:45 +00:00
netteeandGitHub d1bc38478a fix(desktop): cap idle updater polling (#4143)
Generated-By: looper 0.9.7 (runner=worker, agent=codex)
2026-06-11 11:39:59 +00:00
PerishFireandGitHub f9433a7a07 release: harden packaged launcher validation (#3995)
* Unify release metadata publishing

* Allow empty release asset suffix

* Harden beta-s release publishing

* Clean beta Windows release namespace

* Clean Windows launcher namespace

* Retry transient mac notarization uploads

* Control mac notarization upload mode

* Notarize release mac DMGs after build

* Harden release mac DMG notarization retries

* Make beta-s mac updates payload-first

* Bake mac updater metadata URL

* Add unsafe DMG install helper

* Fix beta-s feed and About version

* Improve release validation observability

* Build launcher proto before packaging

* Notarize release-stable mac artifacts

* Enable mac notarization in tools-pack

* test: update packaged release workflow assertions
2026-06-09 11:50:01 +00:00
2ce9d09f41 Fix Windows launcher beta update lifecycle (#3960)
* fix windows beta updater acceptance harness

* fix: harden windows launcher beta updates

* fix: align launcher payload e2e relaunch stub

Generated-By: looper 0.9.5 (runner=fixer, agent=codex)

* fix: gate windows uninstall version sync

Generated-By: looper 0.9.5 (runner=fixer, agent=codex)

* fix: verify launcher payload before activation

Generated-By: looper 0.9.5 (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-06-09 06:00:59 +00:00
netteeandGitHub a58aafa1e6 feat(desktop): add hidden AMR profile menu (#3899)
* 1

* 2

* spec

* feat(desktop): add hidden AMR profile menu

* fix(desktop): rename AMR profile menu

* fix(amr): scope cached models and sync desktop profile changes

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(amr): preserve scoped cache and settings draft

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(amr): reuse scoped models after empty probes

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(web): clear stale AMR cache on profile refresh

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(web): scope AMR recharge links by profile

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(settings): preserve draft env entries on AMR sync

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(web): preserve AMR profile context in side chat

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(web): clear stale AMR selection on profile change

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(daemon): scope AMR connection test model fallback

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(settings): clear stale AMR draft model on profile change

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(amr): align profile switch model resets

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(web): preserve AMR profile links across chat entry points

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(desktop): serialize AMR model clears

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(web): ignore stale AMR poll results after profile changes

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)

* fix(desktop): preserve AMR model on same-profile selection

Generated-By: looper 0.9.6 (runner=fixer, agent=codex)
2026-06-09 02:28:53 +00:00
7a1ad1a438 feat(packaged): add launcher payload updates (#3812)
* feat(packaged): add launcher payload runtime

* ci: focus launcher payload windows smoke

* ci: publish beta mac x64 launcher payload

* test(e2e): harden payload updater smoke

* fix(pack): inject launch config for installed windows smoke

* fix(daemon): allow packaged payload resource roots

* fix(updater): relaunch after payload update

* test(e2e): refresh windows updater UI status

* test(e2e): ensure windows smoke reaches main shell

* test(e2e): skip onboarding before windows updater smoke

* fix(updater): detach windows payload relaunch helper

* test(e2e): run payload smoke without updater dry run

* fix(desktop): relaunch windows payload updates on quit

* fix(updater): preserve installed payload relaunch target

* fix(updater): require launcher target for payload updates

Generated-By: looper 0.9.5 (runner=fixer, agent=codex)

* test(e2e): align mac x64 artifact mode assertion

* test(e2e): canonicalize launcher relaunch root

* fix(updater): validate launcher payload config before activation

Generated-By: looper 0.9.5 (runner=fixer, agent=codex)

* fix(updater): require live launcher target for payload updates

Generated-By: looper 0.9.5 (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-06-07 07:38:57 +00:00
3a21392c46 Fix Electron composer lag and stale generation failures (#3593)
* Keep chat typing and web CSS resolution responsive

Cache the normalized mention index by entity array and scan only concrete @ positions so the composer does not rescan every file/plugin/skill token on each draft update. Link the shared components package at the root importer so Turbopack/PostCSS can resolve the exported component stylesheet from the web CSS entrypoint.

Constraint: Chat composer typing updates run on every keystroke in Electron, and tools-dev/Next evaluates global CSS from the workspace root.
Rejected: Debouncing textarea state updates | would make text entry feel stale and would not remove the expensive synchronous parser path.
Rejected: Relative-importing package source CSS from apps/web | would bypass the package export contract and hardcode package layout into the app stylesheet.
Confidence: high
Scope-risk: narrow
Directive: Keep inline mention parsing proportional to draft mention markers, and keep package CSS imports resolvable through workspace package links.
Tested: pnpm install
Tested: pnpm --filter @open-design/web test -- tests/utils/inlineMentions.test.ts
Tested: pnpm --filter @open-design/web typecheck
Tested: pnpm --filter @open-design/web build
Tested: pnpm guard
Not-tested: Full web Vitest remains blocked by unrelated CSS selector tests observed before this commit.

* Keep composer typing off the render path

Move keystroke-time draft updates into the textarea/ref path while deferring React draft rendering, mention overlay work, picker filtering, and localStorage persistence so Electron input echo stays within frame budget.

Constraint: Electron chat input was visibly lagging for plain text and mention text while the right iframe stayed responsive.

Rejected: Keep the textarea fully controlled | every keystroke still synchronizes the largest ChatComposer render path.

Confidence: high

Scope-risk: moderate

Directive: Keep prompt submission, slash commands, and mention insertion reading draftRef when draft rendering is deferred.

Tested: pnpm guard; pnpm --filter @open-design/web typecheck; pnpm --filter @open-design/web build; pnpm exec vitest run -c vitest.config.ts tests/components/ChatComposer.infinite-render.test.tsx; pnpm exec vitest run -c vitest.config.ts tests/components/ChatComposer.context-pickers.test.tsx; pnpm exec vitest run -c vitest.config.ts tests/utils/inlineMentions.test.ts; Electron inspect eval plain text avg 0.03ms max 0.5ms; Electron inspect eval @ path avg 0.03ms max 0.1ms; HTTP smoke status 200 with no components CSS resolve error.

Not-tested: Full web Vitest suite and Playwright UI suite.

* Keep Electron chat input responsive under heavy projects

Constraint: Electron project views can carry large chat/file DOM and Chromium can throttle or defer visible renderer work under tab/window visibility edge cases.
Rejected: Re-rendering the composer draft on every plain keystroke | it couples textarea input to mention overlay, resize, storage, and project layout work.
Confidence: medium
Scope-risk: moderate
Directive: Keep plain text input on the textarea/ref path; only commit React draft state immediately for mention, slash, chip, or imperative draft mutations.
Tested: pnpm guard; pnpm --filter @open-design/web typecheck; pnpm exec vitest run -c vitest.config.ts tests/components/ChatComposer.infinite-render.test.tsx; pnpm --filter @open-design/desktop test; pnpm --filter @open-design/desktop typecheck; desktop inspect actual project composer with OS SendKeys.
Not-tested: Push/PR remains blocked by GitHub 403 for mimicryluden on nexu-io/open-design.

* Keep heavy project typing isolated from preview layout

Constraint: Electron project panes can carry large DOM histories and preview frames that make textarea paint sensitive to parent layout.

Rejected: Further debouncing ChatComposer input state | app-side handler costs were already low while native textarea updates still lagged.

Confidence: high

Scope-risk: moderate

Directive: Keep the composer mounted through the fixed layer/slot pair so future layout changes do not pull typing back into the split-pane flex reflow path.

Tested: pnpm --filter @open-design/web typecheck; pnpm exec vitest run -c vitest.config.ts tests/components/ChatComposer.infinite-render.test.tsx tests/components/ChatComposer.context-pickers.test.tsx; pnpm guard; pnpm --filter @open-design/web build; desktop inspect fixed-layer DOM and SendKeys probe avg beforeinput->input 1.4ms max 2.5ms

Not-tested: PR publish blocked by GitHub repository permissions if remote still rejects mimicryluden

* Keep stale run recovery from hiding generated previews

Constraint: Completed daemon runs can outlive the in-memory run registry after a restart.

Rejected: Replaying succeeded rows with empty producedFiles | It turns completed messages into failed messages when the registry is gone.

Confidence: high

Scope-risk: narrow

Directive: Only active run statuses should enter daemon reattach recovery.

Tested: vitest generation-preview; vitest ProjectView reattach restore; web typecheck; pnpm guard; web build; desktop DOM eval failureText=false iframeCount=2

Not-tested: Fresh provider generation against an external model

* Keep composer contracts aligned with latest main

Rebase conflict resolution restored the current composer contract while leaving the lower-risk latency fixes in separate layers.

Constraint: The branch was rebased over newer workspace/session context composer contracts.

Rejected: Keeping the older composer conflict side because it removed current ChatComposer props and broke web typecheck.

Confidence: high

Scope-risk: narrow

Directive: Preserve upstream ChatComposer contracts when rebasing input-latency work.

Tested: web typecheck; targeted ChatComposer, inlineMentions, ProjectView generation-preview tests; desktop window-chrome test

Not-tested: Full browser interaction after fork push

* Fix daemon Nix workspace symlink pruning

---------

Co-authored-by: Siri-Ray <2667192167@qq.com>
2026-06-04 10:47:44 +00:00
Tom HuangandGitHub fd1c0ecb93 Feat/optimize style (#3624)
* Refactor ChatComposer and DesignBrowserPanel components for improved functionality and localization

- Introduced new functions in ChatComposer for managing attachment orders and appending staged attachments, enhancing user experience during file uploads.
- Updated ChatPane to clarify the search button's aria-label for better accessibility.
- Enhanced DesignBrowserPanel with new localization keys for browser use inputs and actions, improving clarity across multiple languages.
- Adjusted styles in various components for better layout and user interaction, including updates to the chat input and staged context elements.

* Update AvatarMenu and Chat components for improved functionality and localization

- Modified AvatarMenu to include an optional section parameter for the onOpenSettings callback, enhancing flexibility in opening settings.
- Updated tests for AvatarMenu to verify the correct section is passed when opening settings.
- Adjusted styles in various components, including the ChatComposer and FileViewer, to improve layout and user interaction.
- Enhanced localization strings across multiple languages to reflect changes in chat mode terminology from 'Chat' to 'Ask', improving clarity for users.
2026-06-04 10:22:39 +00:00
goododeo-specandGitHub 18169ee52a Improve export fidelity contract for editable PPTX and PDF readiness (#3628)
* Improve export fidelity contract

* Improve export fidelity contract

* Improve export fidelity contract

* Improve export fidelity contract

* Wait for CSS images in desktop print handshake

* Wait for CSS images in desktop print handshake
2026-06-04 09:13:50 +00:00
6408937564 feat(web): redesign Design Files panel + pick working directory from Home (#3358)
* feat(web): align Design Files panel with Claude reference UI

Redesign the Design Files panel into a continuous grouped table that
mirrors Claude's own Design Files surface: uppercase gray section bands
(Folders / Stylesheets / Scripts / Documents / Images …), flush
full-width rows with a colored icon block + bold name + type subtitle +
right-aligned timestamp, a clean single-line toolbar (breadcrumbs left,
New sketch / Paste / Upload right), a right preview card with a centered
Open action and `Modified … · size · EXT` stats, and a static
USEFUL INFO footer.

Removes the old table/sort-header/kind-filter/pagination/group-toggle
chrome and the conflicting legacy `.app .df-*` overrides in routines.css
that were trumping the panel's own stylesheet via specificity. Preserves
batch select/download/delete, rename, the row context menu,
live-artifacts, plugin-folders, drag-upload, and the reloading overlay.

Adds the designFiles.* section/kind/useful-info i18n keys across all
locales.

* feat: pick a working directory from Home before the project exists

Let users choose a code folder on the Home screen up front, instead of
only being able to replace it after a project is created. The HomeHero
composer gains a folder pill (pick / clear); the chosen path is threaded
through project creation and applied via the working-dir API once the
project id exists.

On desktop the working-dir POST is gated behind a host-minted token, so
add a `dialog:pick-working-dir` IPC handler that shows the native picker
and mints a single-use token bound to the folder, plus a
`pickHostWorkingDir()` bridge + types/normalizer in `@open-design/host`.
The renderer feature-detects the bridge and falls back to the web folder
dialog (no token) otherwise. Native dialogs now allow creating a new
folder inline (`createDirectory` / `ShowNewFolderButton`), and macOS uses
`choose folder` so the panel reliably takes key focus.

Wire the WorkingDirPill into the project composer footer and surface a
reloading state + breadcrumb root label to the Design Files panel while a
replace reindexes. Drop the WorkingDirPill "recent directories"
localStorage list in favor of a single Replace action.

* fix(web): preserve staged Home attachments when picking a working dir

Move the working-dir handoff ahead of the initial upload so staged
attachments land in the external folder instead of the temporary managed
root, and fall back to the browser folder dialog when the desktop host
build does not expose pickWorkingDir.

* fix(web): surface host pick errors and normalize Windows dir basenames

When the desktop host is present but cannot mint a working-dir token,
surface the error instead of falling back to the browser folder dialog —
the tokenless raw path would be rejected by the desktop auth gate as a
late create-time failure. Only the pure web path (no token gate) keeps
the dialog fallback. Also split the Home pill basename on both path
separators so Windows paths show the folder name, not the full path.

* fix(web,desktop): harden Home working-dir handoff against auth/token failures

Run the desktop-auth handshake before minting the Home working-dir token
so a missed startup registration fails up front instead of as a rejected
deferred POST. Surface a create-time error toast when the working-dir
handoff fails (expired ~60s token or daemon rejection) instead of
silently leaving the project in the managed root while the user believes
their folder was applied.

* fix(web): abort create on failed working-dir handoff and always show root crumb

When the pre-create working-dir handoff fails, short-circuit the rest of the
Home submit path (skip the staged-attachment upload and auto-send) so the first
run cannot proceed against the managed `.od/projects/<id>` tree the user did not
choose, and reword the error toast accordingly. Always render the Design Files
root breadcrumb, falling back to the `designFiles.crumbs` label when no
rootDirName exists, so the toolbar is not blank on the default managed-storage
view. Adds regressions for the short-circuit and default-root crumb cases.

Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code)

* fix(web): normalize Windows separators in WorkingDirPill basename

shortPath() split only on '/', so a Windows working dir like C:\work\repo
rendered as the full absolute path in the footer pill instead of the
folder name. Split on both separators to match HomeHero/ProjectView, and
add a regression covering the backslash path.

Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code)

---------

Co-authored-by: qiongyu1999 <2694684348@qq.com>
2026-06-04 05:48:57 +00:00
Tom HuangGitHubopen-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com>qiongyu1999Siri-Ray
c6722d2671 feat: Lexical composer, interactive terminals, comment attachments & browser reference board (#3516)
* feat(daemon): add interactive terminal support with node-pty

- Introduced a new terminal service to manage interactive terminal sessions.
- Added routes for creating, streaming, and managing terminal sessions in the daemon.
- Integrated terminal functionality into the CLI, allowing users to open interactive shells.
- Updated project routes to support conversation seeding for side chats.
- Enhanced the web application to include terminal tab functionality and UI components.

This feature enables users to interact with a terminal directly within the application, enhancing the overall user experience and providing a more integrated development environment.

* feat(web): implement embedded browser module in Design Files workspace

- Added a `+` icon to the Design Files tab for opening a new Browser module.
- The Browser module supports navigation features including back, forward, refresh, and address input.
- Integrated a curated list of design reference URLs for user convenience.
- Implemented browser data clearing functionality via IPC.
- Enhanced desktop runtime to support embedded browser with appropriate security measures.
- Added tests for browser functionality and URL handling.

This commit establishes a new workspace for browsing and referencing design resources directly within the application, improving user experience and accessibility to design tools.

* refactor(web): enhance add tab menu functionality in FileWorkspace

- Updated the add tab button to toggle the visibility of the menu with improved accessibility attributes.
- Refactored the add menu to be portaled to the document body for better positioning and visibility.
- Adjusted CSS styles for the add menu to use fixed positioning and increased z-index for proper layering.
- Minor CSS adjustments in entry layout for consistent padding.

These changes improve the user experience when adding new modules in the FileWorkspace, ensuring the add menu is more accessible and visually consistent.

* feat(daemon): introduce session mode for conversations

- Added a new `session_mode` column to the `conversations` table with a default value of 'design'.
- Implemented logic to handle `session_mode` in conversation creation, updates, and retrieval.
- Enhanced the API to support `session_mode` in conversation requests, allowing for 'chat' or 'design' modes.
- Updated the web application to include a session mode toggle, enabling users to switch between chat and design modes seamlessly.
- Adjusted system prompts to reflect the current session mode, providing context-aware responses.

This feature enhances the user experience by allowing for more flexible conversation management, catering to different interaction styles.

* feat(web): enhance navigation and settings functionality in DesignBrowserPanel and EntryShell

- Introduced a navigation stack in DesignBrowserPanel to manage back and forward navigation states.
- Updated the browser navigation logic to handle URL history and improve user experience.
- Added a settings menu in EntryShell for quick access to language and appearance options.
- Implemented CSS styles for the new settings menu, ensuring a consistent and user-friendly interface.
- Enhanced tests for navigation functionality and settings menu interactions.

These changes improve the overall usability of the application by streamlining navigation and providing easy access to settings.

* feat(daemon): enhance conversation session mode handling

- Added a new `mode` flag to CLI commands for project and conversation creation, allowing users to specify 'design' or 'chat' modes.
- Implemented `normalizeChatSessionModeFlag` function to validate and normalize session mode inputs.
- Updated project routes to handle session mode during conversation creation and updates.
- Enhanced web components to support session mode changes, including new props and handlers for managing session modes in conversations.
- Adjusted UI elements to reflect the current session mode, improving user experience and interaction flexibility.

This update provides a more robust framework for managing conversation modes, catering to diverse user needs and enhancing overall functionality.

* feat(web): enhance HandoffButton and DesignBrowserPanel with improved functionality and styling

- Updated HandoffButton to support framework-specific CLI prompts and improved local project path handling.
- Enhanced DesignBrowserPanel to manage browser history with favicon support and improved address display.
- Introduced new utility functions for formatting addresses and extracting hostnames.
- Refactored CSS styles for better layout and responsiveness across components.
- Added tests for new functionalities in HandoffButton and DesignBrowserPanel, ensuring robust behavior.

These changes improve user experience by streamlining the handoff process and enhancing the design browsing capabilities within the application.

* feat(web): enhance HandoffButton and ProjectView with improved instructions handling and UI updates

- Updated HandoffButton to include a tabbed interface for switching between editor and CLI options, enhancing user experience.
- Added support for opening the AMR website directly from the HandoffButton.
- Refactored ProjectView to implement a modal for custom instructions, allowing users to edit and review instructions more intuitively.
- Improved CSS styles for project instructions modal and handoff menu, ensuring better layout and responsiveness.
- Added keyboard accessibility for closing the instructions modal with the Escape key.

These changes streamline the handoff process and improve the usability of custom instructions within the application.

* feat(daemon): add social share functionality and project folder management

- Introduced new `share` command in CLI for building localized social-share targets for Open Design projects.
- Implemented `printShareUsage` and `runShare` functions to handle share requests and display usage instructions.
- Added API routes for social sharing, allowing users to create shareable links for projects.
- Enhanced project routes with new endpoints for listing and creating project folders, improving project organization.
- Updated relevant files and tests to support new functionalities, ensuring robust behavior.

These changes enhance user experience by facilitating social sharing and better project management within the application.

* feat(web): enhance DesignBrowserPanel and DesignFilesPanel with improved address formatting and drag-and-drop functionality

- Refactored `formatAddressDisplay` to utilize a new `formatAddressDisplayParts` function, separating URL and title handling for better clarity.
- Updated `DesignFilesPanel` to improve drag-and-drop interactions, including enhanced directory navigation and file management features.
- Adjusted CSS styles for better visual consistency and responsiveness across components.
- Added tests for new functionalities in `DesignBrowserPanel` and `DesignFilesPanel`, ensuring robust behavior.

These changes improve user experience by streamlining address formatting and enhancing file management capabilities within the application.

* feat(web): enhance DesignBrowserPanel and DesignFilesPanel with new reference categories and improved folder creation

- Added new reference categories in DesignBrowserPanel, including 'Inspiration', 'Real Interfaces', 'Color', 'Typography', and more, each with curated design resources.
- Improved folder creation logic in DesignFilesPanel to suggest names based on existing folders, enhancing user experience.
- Updated CSS styles for better layout and responsiveness across components, particularly in control rows and search functionalities.
- Added tests for new reference categories and folder creation features, ensuring robust functionality.

These changes enrich the design resource catalog and streamline folder management, improving overall usability within the application.

* feat(web): implement reference icon functionality and enhance social share features

- Replaced favicon URL generation with a new `referenceIconUrl` function to provide reliable icons for curated design sites, improving visual consistency in the DesignBrowserPanel.
- Updated the FileViewer component to enhance social share functionality, including clearer messaging for protected deployments and improved UI for sharing links.
- Added CSS styles to support new visual states for social share components, ensuring better user experience.
- Expanded tests for the new `referenceIconUrl` function and social share interactions, ensuring robust functionality.

These changes enhance the design resource presentation and improve the sharing experience within the application.

* feat(web): enhance DesignFilesPanel and FileViewer with improved folder management and social share functionality

- Added optimistic folder path management in DesignFilesPanel to improve user experience during folder creation.
- Updated social share logic in FileViewer to handle protected deployments more effectively, ensuring clearer messaging and UI updates.
- Refactored CSS styles for better layout and responsiveness in both components, enhancing overall usability.
- Expanded tests for new folder management features and social share interactions, ensuring robust functionality.

These changes streamline folder management and enhance the social sharing experience within the application.

* feat(daemon): enhance project tab management with new state handling

- Updated database schema to include a new `state_json` column in the `tabs_state` table for improved project tab state management.
- Implemented functions to normalize and parse project tab states, including handling browser workspace tabs.
- Modified `listTabs` and `setTabs` functions to utilize the new state management features, allowing for better tracking of active tabs and saved states.
- Refactored related types in the contracts and web applications to support the new tab state structure.

These changes improve the functionality and user experience of managing project tabs within the application.

* feat(web): enhance project tab management and browser tab functionality

- Updated project routes and server logic to include `browserTabs` in the request body, improving tab state management.
- Implemented validation for `browserTabs` to ensure it is an array, enhancing error handling.
- Refactored `setTabs` function to accommodate the new structure for managing tabs, including browser-specific tabs.
- Added tests for browser tab state persistence and management in the new `project-tabs-state.test.ts` file, ensuring robust functionality.

These changes improve the user experience by providing better management and persistence of project and browser tabs within the application.

* feat(web): enhance ProjectView with improved chat send management and UI updates

- Added support for queue-only chat sends, allowing for better handling of messages during busy conversations.
- Refactored chat send functions to improve state management and persistence of queued messages.
- Updated CSS styles in the DesignFilesPanel for better layout and responsiveness, including search control enhancements.
- Expanded tests for new chat send functionalities and search interactions, ensuring robust behavior.

These changes improve the user experience by streamlining chat interactions and enhancing the overall design file management interface.

* feat(web): improve project tab state management and caching

- Enhanced the `loadTabs` function to utilize cached tab states, improving performance and user experience during data fetching.
- Implemented `normalizeTabsState` and caching functions to manage tab states effectively, including validation and error handling.
- Updated `writeCachedTabs` to ensure the latest state is stored in local storage, facilitating better persistence of tab information.
- Modified `listTabs` in the daemon to include `updatedAt` in the state retrieval, allowing for more accurate tracking of tab updates.

These changes streamline tab management and enhance the overall responsiveness of the application.

* feat(web): integrate Lexical for enhanced text composition and mention handling

- Added Lexical as a dependency to improve text composition capabilities within the chat interface.
- Implemented mention functionality with the creation of `MentionNode` and related serialization/deserialization logic for inline mentions.
- Enhanced `ChatComposer` and `ChatPane` components to support queue-only message sending and improved state management for queued messages.
- Updated `DesignBrowserPanel` and `PreviewDrawOverlay` to incorporate new features for capturing and annotating browser snapshots.
- Refactored various components to streamline interactions and improve user experience during chat and design tasks.

These changes significantly enhance the text editing experience and provide better management of chat interactions, improving overall usability in the application.

* feat(workspace): integrate terminal viewer and enhance chat functionality

- Added a new terminal viewer component with customizable themes and improved styling for better user experience.
- Integrated terminal functionality into the workspace, allowing users to interact with a terminal directly within the application.
- Updated chat components to support active conversation states, enabling seamless message handling and interaction.
- Refactored chat-related props and state management to enhance performance and maintainability.
- Removed deprecated file tree explorer components to streamline the workspace interface.

This update enhances the overall functionality of the workspace, providing users with a more integrated and responsive environment for both terminal and chat interactions.

* feat(workspace): enhance chat and session mode functionality

- Introduced a new `+` launcher in the workspace for easy access to project files and new tabs, including Side Chat and Terminal.
- Added Side Chat functionality that allows users to create context-aware conversations based on existing chats.
- Implemented a new terminal tab type for interactive terminal sessions using `node-pty`, enabling users to run shell commands directly within the workspace.
- Enhanced chat functionality with a new session mode toggle, allowing users to switch between 'design' and 'chat' modes seamlessly.
- Added a feature to copy chat responses as markdown to the clipboard, improving usability and sharing capabilities.
- Updated various components and styles to support these new features, ensuring a cohesive user experience.

This update significantly improves the workspace's interactivity and usability, providing users with more tools for collaboration and development.

* feat(workspace): enhance session mode toggle and chat functionality

- Improved the SessionModeToggle component to include localized guidance cards that provide context-aware descriptions for each mode.
- Updated the UI to display a popover with mode descriptions when hovering over options, enhancing user understanding of the available modes.
- Added a new copy button in the AssistantMessage footer to allow users to copy responses as raw Markdown, improving usability for external documentation.
- Enhanced localization support by updating i18n keys and translations for various languages, ensuring consistent user experience across different locales.
- Refactored styles for the session mode toggle and associated components to improve layout and responsiveness.

This update significantly enhances the user experience by providing clearer guidance and improved functionality in chat interactions.

* feat(styles): enhance session mode toggle styling for improved visibility

- Added new CSS rules to ensure the session mode toggle popover and hover cards are displayed correctly with increased z-index and visibility.
- Updated styles for various chat components to maintain consistent positioning and overflow behavior when session mode elements are present.
- Improved overall layout responsiveness for chat interactions, enhancing user experience during mode transitions.

This update refines the visual presentation of session mode toggles, ensuring they are more accessible and user-friendly.

* feat(web): finish Lexical composer input with atomic mention pills

* fix(web): make browser reference board scroll with a pinned toolbar

The browser tab's default Reference Board (.db-start) is wrapped by
PreviewDrawOverlay's position:absolute container, which is not a flex
parent — so .db-start's flex:1 1 auto never bounded its height and the
board grew to its content height instead of scrolling (and the sticky
.db-reference-toolbar could not pin). Fill the overlay with height:100%
like the .db-webview/.db-fallback siblings already do, restoring scroll
and the sticky toolbar.

* test(daemon): expect updatedAt in persisted tab state round-trip

listTabs() returns the tabs_state row's updatedAt timestamp on the
saved-state path, but these two toEqual assertions predated that field
and failed strictly. Match the real shape with expect.any(Number).

* feat(chat): enhance ChatComposer with session mode management and UI improvements

- Introduced a new `sessionMode` prop to the ChatComposer, allowing users to switch between different session modes (e.g., 'design').
- Added a SessionModeToggle component for improved user interaction and visibility of session options.
- Updated the ToolsTab type to reflect the removal of the pet option, streamlining the tools available in the composer.
- Refactored styles to enhance the visibility and positioning of session mode elements, ensuring a better user experience during mode transitions.
- Improved the handling of draft state and user interactions within the composer, enhancing overall functionality.

These changes significantly improve the ChatComposer's usability and flexibility, providing users with clearer options and a more responsive interface.

* feat(chat): implement caret floating layer for mention and slash popovers

- Introduced a new `CaretFloatingLayer` component to manage the positioning of mention and slash command popovers relative to the caret.
- Enhanced `ChatComposer` to utilize the caret rectangle for accurate popover placement, improving user experience during text input.
- Updated `LexicalComposerInput` to pass caret position data to the trigger handling logic, allowing for dynamic popover adjustments.
- Refactored styles for popovers to ensure consistent appearance and behavior, including improved animations and responsiveness.
- Added accessibility features to mention and slash popovers, enhancing usability for keyboard navigation.

These changes significantly improve the interaction model for mentions and commands within the chat interface, providing a more intuitive and responsive user experience.

* feat(chat): update mention tab order and improve search functionality

- Reordered the mention tab sections in the ChatComposer to prioritize 'Design files' over other categories, enhancing user experience during mentions.
- Updated the search prompt to reflect the new tab order, ensuring clarity in search functionality.
- Enhanced the mention selection logic to accommodate the new tab structure, allowing for a more intuitive navigation experience.
- Added tests to verify the correct display and functionality of the updated mention tabs and search behavior.

These changes significantly improve the usability of the mention feature within the chat interface, making it easier for users to find and select relevant items.

* feat(chat): enhance context management in ChatComposer and HomeHero

- Added functionality to manage MCP servers and connectors within the ChatComposer, allowing users to remove these contexts seamlessly.
- Updated the HomeHero component to support the selection and removal of MCP servers and connectors, improving context handling in user interactions.
- Enhanced the search prompt to include files, ensuring users can search across all relevant categories.
- Refactored related components and styles for better integration and user experience.
- Added tests to verify the correct functionality of the new context management features.

These changes significantly improve the usability of context features in the chat interface, making it easier for users to manage their interactions effectively.

* feat(chat): enhance message handling with session mode and plugin snapshot support

- Added new columns to the database schema for `session_mode` and `applied_plugin_snapshot_json` to support enhanced message context.
- Updated the `upsertMessage` and `listMessages` functions to handle the new fields, ensuring messages can store and retrieve session mode and plugin snapshot data.
- Enhanced the `ChatComposer` to manage and send the applied plugin snapshot as part of the message context, improving user interaction with plugins.
- Introduced a new `MessageSessionModeChip` component to visually represent the session mode in the chat interface.
- Updated styles for better presentation of session mode and plugin context within messages, enhancing user experience.

These changes significantly improve the context management capabilities in the chat interface, allowing for richer interactions and better tracking of session-specific data.

* feat(chat): add annotation handling and UI improvements in ChatComposer and PreviewDrawOverlay

- Implemented functionality to stage draw annotations into the composer input without sending, enhancing user interaction.
- Added a new button in the PreviewDrawOverlay to allow users to append notes to the input, improving workflow flexibility.
- Updated the ChatComposer tests to verify the correct staging of annotations and their integration into the input.
- Enhanced internationalization support by adding new translation keys for annotation actions across multiple languages.

These changes significantly improve the user experience by providing more intuitive annotation handling and better integration within the chat interface.

* feat(capture): implement page capture functionality and enhance folder management dialogs

- Added new capture functionality to allow users to take snapshots of the current page, improving user interaction with visual content.
- Introduced in-app dialogs for folder creation and moving files, replacing the unsupported window.prompt in the Electron desktop host, enhancing usability across platforms.
- Updated the DesignFilesPanel to support these new dialogs, ensuring a seamless experience for managing project files.
- Enhanced internationalization support by adding new translation keys for folder management actions across multiple languages.

These changes significantly improve the user experience by providing intuitive capture options and streamlined file management within the application.

* feat(projects): implement folder deletion and enhance project file management

- Added a new API endpoint to delete project folders, improving the file management capabilities within the application.
- Introduced utility functions for ensuring project subdirectories and safely deleting folders, enhancing the robustness of folder operations.
- Updated the DesignFilesPanel and FileWorkspace components to support folder deletion actions, providing users with a more intuitive interface for managing project files.
- Enhanced internationalization support by adding new translation keys for folder management actions.

These changes significantly improve the user experience by streamlining folder management and providing clearer options for users to organize their projects effectively.

* feat(composer): enhance BoardComposerPopover with image attachment functionality

- Added support for attaching images to comments, allowing users to upload and preview images directly within the composer.
- Implemented new handlers for image input changes and clipboard pasting, improving the user experience for image uploads.
- Updated the component's props to include image-related callbacks and state management for attached images.
- Enhanced styles for image thumbnails and removal buttons, ensuring a cohesive design with the existing comment popover interface.

These changes significantly improve the functionality of the BoardComposerPopover, providing users with a more interactive and visually rich commenting experience.

* feat(file-viewer): enhance comment attachment functionality with image support

- Updated the `onSendBoardCommentAttachments` prop to accept an additional `images` parameter, allowing for image attachments alongside comments.
- Introduced state management for handling attached images, including functions to add and remove images, and to generate previews.
- Implemented a modal for previewing attached images, improving user interaction when managing comment attachments.
- Updated the `FileWorkspace` component to reflect changes in the props, ensuring consistency across components.

These enhancements significantly improve the commenting experience by enabling users to attach and preview images directly within the file viewer.

* feat(home-hero, project-view, styles): enhance functionality and user experience

- Updated the HomeHero component to prevent unnecessary state changes during programmatic updates, improving user interaction with prompts.
- Enhanced the ProjectView component to support image attachments alongside comments, allowing for a more versatile commenting experience.
- Implemented a new image upload process that queues tasks efficiently, ensuring smooth handling of comment attachments.
- Added CSS to reserve scrollbar space in design files, preventing layout shifts when scrollbars appear, thus enhancing visual stability.

These changes collectively improve the user experience by streamlining interactions and ensuring consistent UI behavior across components.

* feat(preview-comments, chat): enhance comment functionality with attachment support

- Added support for `attachments_json` in the `preview_comments` table, allowing users to attach files to comments.
- Updated relevant functions to handle attachments, including `upsertPreviewComment` and `listPreviewComments`, ensuring attachments are properly managed and displayed.
- Enhanced the `CommentSidePanel` to render attached files, providing users with a visual representation of their attachments.
- Improved the `BoardComposerPopover` and `ChatPane` components to support image attachments, including drag-and-drop functionality for reordering queued sends.

These changes significantly enhance the commenting experience by enabling users to attach and manage files directly within the chat interface, improving overall usability and interaction.

* refactor(comment-attachments): rename attachment normalization functions for clarity

- Updated the `normalizeCommentAttachments` function to `normalizePreviewCommentAttachments` for better context in handling preview comment attachments.
- Adjusted the `upsertPreviewComment` and `normalizePreviewComment` functions to utilize the renamed attachment normalization function.
- Added tests to ensure that image attachments are correctly saved and retrieved, addressing a regression issue with attachment persistence.

These changes enhance code clarity and maintainability while ensuring the functionality for handling comment attachments remains robust.

* feat(comment-attachments): enhance comment submission with image and note validation

- Updated the `upsertPreviewComment` function to require either a text note or at least one image attachment for comment submission, improving validation logic.
- Modified the `BoardComposerPopover` to allow saving comments with only images, enhancing user experience by simplifying the commenting process.
- Adjusted the `FileViewer` to support saving comments with image-only notes, ensuring consistency across components.
- Improved styles in the chat and home hero components for better visual representation of attachments and comments.

These changes collectively enhance the commenting functionality, providing users with more flexibility in how they submit comments while ensuring robust validation.

* feat(project-view): implement auto-start for queued chat sends

- Replaced the `startingQueuedChatSendIdRef` with a state variable `queuedAutoStartBlocked` to manage the auto-start behavior of queued chat sends.
- Updated the `useEffect` to ensure that queued sends are processed one at a time after the active conversation completes, enhancing the chat experience.
- Added a test to verify that queued sends auto-start correctly after the active run finishes, ensuring reliable functionality.

These changes improve the handling of queued chat messages, providing a smoother user experience during conversations.

* feat(project-view): refine auto-start logic for queued chat sends

- Replaced the state variable `queuedAutoStartBlocked` with a reference `startingQueuedChatSendIdRef` to manage the auto-start behavior of queued chat sends more effectively.
- Updated the `useEffect` to ensure that queued sends are processed sequentially, improving the handling of chat messages during active conversations.
- Introduced a new state variable `queuedAutoStartTick` to track the auto-start process, enhancing the responsiveness of the chat interface.

These changes improve the reliability and user experience of the chat functionality by ensuring queued messages are handled smoothly and efficiently.

* feat(comment-attachments): improve attachment handling in preview comments

- Updated the `upsertPreviewComment` function to merge existing and incoming attachments, ensuring that image attachments are preserved when updating comments without new files.
- Introduced a new helper function, `mergePreviewCommentAttachments`, to handle the merging of attachments without duplicates, enhancing the robustness of attachment management.
- Added tests to verify the correct merging of attachments and the preservation of existing attachments during comment updates, improving overall functionality and user experience.

These changes enhance the commenting system by providing better management of image attachments, ensuring users can update comments seamlessly while retaining their attached images.

* feat(BoardComposerPopover): enhance popover positioning and measurement

- Updated the `popoverAnchorStyle` function to incorporate viewport scroll positions, ensuring the popover remains within visible bounds.
- Introduced a new `PopoverSize` type to manage measured dimensions, improving the accuracy of popover placement.
- Implemented a `useLayoutEffect` to dynamically measure the popover size and adjust its position accordingly, enhancing user experience during interactions.
- Added tests to verify that the popover correctly adjusts its position based on target and viewport dimensions, ensuring it remains fully visible.

These changes improve the usability of the BoardComposerPopover by ensuring it is properly positioned within the viewport, enhancing the overall commenting experience.

* feat(comment-attachments): enhance image attachment handling in comments

- Updated the `normalizeCommentAttachments` function to include image attachments in the comment payload, allowing comments to be submitted with only images.
- Introduced a fallback message for comments that consist solely of image attachments, improving user guidance.
- Enhanced the `renderCommentAttachmentHint` function to display image attachment details, ensuring users are informed about attached images.
- Added tests to verify that image attachments are preserved in comment submissions and correctly rendered in hints, improving overall functionality and user experience.

These changes enhance the commenting system by providing better support for image-only comments, ensuring users can effectively utilize image attachments in their interactions.

* feat(comment-attachments): refine comment context handling and enhance drag-and-drop functionality

- Updated the `normalizeCommentAttachments` function to conditionally omit comment text when the context is set to 'query', improving clarity in comment submissions.
- Enhanced the `renderCommentAttachmentHint` function to only display comments when not in 'query' context, ensuring a cleaner output.
- Implemented drag-and-drop functionality in the `CommentSidePanel` for reordering comments, improving user interaction and organization of comments.
- Added tests to verify the correct handling of comment context and the functionality of the drag-and-drop feature, ensuring robust performance.

These changes enhance the commenting system by providing clearer context management and improved usability through drag-and-drop capabilities.

* feat(FileViewer, ProjectView): enhance comment attachment handling and status updates

- Updated the `FileViewer` component to manage the state of sent comment IDs, ensuring that active previews are correctly updated after sending comments.
- Refined the `ProjectView` component to filter out comment attachments from the board-batch source and update their status to 'applying' during processing, improving user feedback on attachment handling.
- Introduced logic to handle the removal of sent comment IDs from the preview, enhancing the overall user experience when managing comments and attachments.

These changes improve the functionality and responsiveness of the commenting system, providing clearer feedback and better management of comment attachments.

* feat(conversation-forking): introduce message-based conversation forking

- Added the ability to fork conversations from a specific message, enhancing the chat experience by allowing users to create new conversations that inherit context up to a chosen point.
- Updated the CLI commands and help documentation to reflect the new `--fork-after` option, which specifies the message ID to stop copying from.
- Enhanced the backend to handle the new forking logic, ensuring that only messages up to the specified ID are included in the new conversation.
- Implemented tests to verify the forking functionality, ensuring robust performance and correct behavior when forking conversations.

These changes improve the flexibility of conversation management, allowing users to create tailored discussions based on previous interactions.

* feat(terminal-service): enhance session output management and memory handling

- Introduced new parameters for managing session output, including `maxBufferBytes`, `exitTailBytes`, `flushIntervalMs`, and `flushThresholdBytes`, to optimize memory usage and performance.
- Implemented a `trimBuffer` function to efficiently evict old events based on byte and count limits, improving memory management during active sessions.
- Added logic to coalesce buffered PTY output into single `data` events, reducing the frequency of event emissions and enhancing performance during high-throughput scenarios.
- Updated session event structure to include `byteLength`, allowing for better tracking of output size and memory usage.

These changes improve the efficiency and responsiveness of terminal sessions, ensuring better resource management and user experience.

* feat(workspace-context): enhance project attachment handling and workspace context management

- Introduced `formatProjectAttachmentHint` function to render project attachments in a user-visible order, improving clarity for users referencing attachments.
- Added `normalizeWorkspaceContextItems` function to standardize workspace context items, ensuring consistent handling of various context types.
- Updated `mergeRunContextSelections` to include workspace items, enhancing the context management during chat interactions.
- Enhanced `renderRunContextPrompt` to display active workspace context, providing users with better visibility of their current workspace state.
- Implemented tests for new functions to ensure robust functionality and correct behavior in handling project attachments and workspace contexts.

These changes improve the user experience by providing clearer context and better management of project attachments within the application.

* feat(database, chat): enhance message and conversation data structure

- Added `run_context_json` to the `messages` table schema to store contextual information for each message.
- Updated migration logic to include the new `run_context_json` field and ensure backward compatibility.
- Enhanced conversation retrieval to include `messageCount`, providing better insights into the number of messages per conversation.
- Improved attachment handling in the `ChatComposer` component by introducing ordering logic for attachments, ensuring a consistent user experience.
- Refactored `SessionModeToggle` to simplify state management and improve tooltip visibility.

These changes enhance data management and user interaction within the chat application, providing clearer context and improved functionality.

* feat(attachment-handling): improve attachment sorting and context management

- Introduced `sortAttachmentsByUserOrder` function to ensure attachments are displayed in a user-defined order, enhancing clarity and usability.
- Updated `historyWithApiAttachmentContext` to utilize the new sorting function, improving the context provided with message histories.
- Refactored `buildAnthropicMessageContent` to apply sorting for image attachments, ensuring consistent handling across different message types.

These changes enhance the user experience by providing better organization and visibility of attachments within the chat application.

* feat(chat): enhance conversation listing and loading states

- Improved the SQL query for listing conversations to include message counts, providing better insights into conversation activity.
- Added loading states to the ChatPane component, enhancing user experience during data fetching.
- Implemented a search feature in the conversation history, allowing users to filter conversations by title for easier navigation.
- Updated styles for loading indicators and conversation list to improve visual feedback during loading states.

These changes enhance the usability and responsiveness of the chat interface, providing users with clearer context and improved interaction capabilities.

* feat(chat): optimize suggestion filtering and enhance design system integration

- Refactored suggestion filtering in the ChatComposer component to utilize `useMemo`, improving performance by memoizing results based on dependencies.
- Added new props in ChatPane for handling plugin and design system details, enhancing the integration of these features within the chat interface.
- Updated the FileWorkspace component to manage tab states for design system and browser tabs, improving user navigation and context management.
- Introduced modals for displaying plugin and design system details in the ProjectView, enhancing user experience by providing contextual information.

These changes improve the efficiency of suggestion handling and enhance the overall user experience in managing plugins and design systems within the chat application.

* fix(chat): adjust styling and layout for improved chat interface

- Reduced the conversation row height in ChatPane for better alignment with design specifications.
- Updated CSS styles across various components to enhance layout consistency, including adjustments to margins, padding, and flex properties.
- Improved visual feedback and responsiveness in chat elements, ensuring a more cohesive user experience.

These changes refine the chat interface, making it more visually appealing and user-friendly.

* feat(comments): implement structural equality checks for comment snapshots

- Added `commentSnapshotOverlayEqual` and `commentSnapshotEqual` functions to compare comment snapshots based on their structural properties, improving performance by avoiding unnecessary state updates in the `FileViewer` component.
- Updated `HtmlViewer` to utilize these equality checks, optimizing the handling of live comment targets during pointer movements and hover events.
- Enhanced the overall responsiveness of the comment system by preventing redundant re-renders when comment snapshots remain unchanged.

These changes enhance the efficiency of comment handling and improve user experience in the commenting interface.

* feat(chat): enhance comment attachment sorting and order management

- Introduced `sortChatCommentAttachmentsByOrder` function to ensure comment attachments are displayed in a user-defined order, improving clarity and usability.
- Updated the `currentCommentAttachments` function to utilize the new sorting logic, enhancing the organization of attachments.
- Adjusted the order assignment for visual attachments to ensure consistent handling based on existing attachment orders.

These changes improve the user experience by providing better organization and visibility of comment attachments within the chat application.

* feat(chat): enhance queued send strip with overflow handling and styling improvements

- Added overflow handling to the queued send strip, allowing for better visibility of additional queued items when the list exceeds the visible limit.
- Updated CSS styles for the chat components, including adjustments to layout, padding, and font sizes to improve overall aesthetics and usability.
- Refactored the structure of the queued send row to utilize a grid layout, enhancing alignment and responsiveness of the elements within the chat interface.

These changes improve the user experience by providing clearer visibility of queued messages and a more polished interface.

* feat(database): add index for created_at and enhance comment retrieval

- Introduced a new index on `preview_comments` for `created_at` to optimize query performance when retrieving comments.
- Updated the `listPreviewComments` function to order results by `created_at` and `rowid`, improving the organization of displayed comments.
- Enhanced the test suite to verify the injection of the new URL preview selection bridge and its functionality in various scenarios.

These changes improve the efficiency of comment retrieval and enhance the user experience in the commenting interface.

* feat(tooltip): implement tooltip system for enhanced user guidance

- Introduced a new `TooltipLayer` component to manage tooltip display across the application, improving user interaction by providing contextual information on hover and focus.
- Updated various components to utilize the tooltip system, including buttons and icons, ensuring consistent tooltip behavior and styling.
- Enhanced CSS styles for tooltips, improving visibility and responsiveness, while maintaining a cohesive design across the application.

These changes enhance the user experience by providing clearer guidance and improving the overall usability of interactive elements.

* feat(tooltip): enhance tooltip integration across components

- Updated various components to include tooltip functionality, improving user guidance with contextual information on hover and focus.
- Added `data-tooltip` and `data-tooltip-placement` attributes to buttons and interactive elements for consistent tooltip behavior.
- Enhanced CSS styles to ensure tooltips are displayed correctly and responsively, maintaining a cohesive design across the application.

These changes improve the overall user experience by providing clearer guidance and enhancing the usability of interactive elements.

* feat(project-view): refactor comment handling and enhance tooltip positioning

- Introduced `mergeSavedPreviewComment` function to streamline the management of preview comments, improving clarity and maintainability.
- Updated `ProjectView` to utilize the new comment merging function, enhancing the efficiency of comment updates.
- Refactored `TooltipLayer` to use x and y coordinates for positioning, improving tooltip display accuracy and responsiveness.
- Enhanced CSS styles for tooltips, ensuring better visibility and layout consistency across the application.

These changes improve the user experience by providing more efficient comment handling and refined tooltip interactions.

* feat(design-files): enhance workspace hint and file handling in project context

- Introduced `formatDesignFilesWorkspaceHint` function to provide a detailed overview of the current Design Files workspace, including folder and file listings.
- Added limits for the number of folders and files displayed to improve clarity and prevent overwhelming users with excessive information.
- Updated the `startServer` function to integrate the new workspace hint, ensuring that the context of existing project files and folders is communicated effectively.
- Enhanced tests for the new workspace hint functionality to ensure accurate representation of project context.

These changes improve user experience by providing clearer insights into the Design Files workspace and facilitating better project management.

* feat(composer): atomic @mention keyboard navigation and deletion

* feat(database): add attachments_json field to comments and enhance migration logic

- Introduced `attachments_json` field in the database schema for comments to support attachment storage.
- Updated migration functions to include the new field, ensuring existing data is properly migrated.
- Refactored related SQL queries to accommodate the new field, improving data handling for comments.

These changes enhance the comment functionality by allowing attachments to be stored and retrieved effectively.

* chore(nix): refresh pnpm deps hash

* feat(chat-composer): implement design toolbox for enhanced design actions

- Added a new design toolbox feature to the ChatComposer, allowing users to access various design actions such as 'auto-match', 'motion', and 'visual-polish'.
- Introduced a state management system for the design toolbox, including hooks for opening and closing the toolbox.
- Enhanced the user interface with new components and styles for the design toolbox, improving accessibility and usability.
- Implemented functionality to apply design actions directly from the toolbox, streamlining the design workflow.
- Added tests to ensure the correct behavior of the design toolbox and its interactions within the ChatComposer.

These changes significantly enhance the design capabilities within the ChatComposer, providing users with a more efficient and intuitive design experience.

* feat(chat-composer): enhance design toolbox resource management

- Expanded the design toolbox functionality in ChatComposer to include a comprehensive resource index, allowing for better organization and retrieval of skills, plugins, MCP servers, templates, connectors, and project files.
- Introduced new types and interfaces to support the expanded resource management, improving type safety and clarity in the codebase.
- Updated the design toolbox action descriptions and search functionality to reflect the new resource capabilities, enhancing user experience.
- Added tests to validate the new resource indexing and search features, ensuring robust functionality.

These enhancements significantly improve the design workflow by providing users with a more organized and efficient way to access various design resources.

* feat(workspace): enhance workspace context management and UI integration

- Introduced a new function `renderWorkspaceContextToolHints` to provide contextual hints based on the type of workspace items (browser, terminal, files, live artifacts).
- Updated `ChatComposer`, `ChatPane`, and `FileWorkspace` components to support and display workspace context items, improving user interaction and accessibility.
- Enhanced the `QuickSwitcher` and `TabLauncherMenu` components to include workspace context items in search results, allowing users to navigate between tabs and files more efficiently.
- Added new translations and updated existing ones to reflect the inclusion of workspace tabs in the user interface.

These enhancements significantly improve the usability and functionality of the workspace, providing users with better context and navigation options.

* test(e2e): assert Lexical composer content with toHaveText, not toHaveValue

The chat composer and home hero input are now Lexical contenteditable
editors, not native form controls, so Playwright's toHaveValue (form-only)
fails with "Not an input element". Switch all chat-composer-input and
home-hero-input content assertions to toHaveText, and assert multi-line
soft-break cases with separate toContainText checks since the editor's
textContent collapses the newline (the newline reaching the sent payload
is already covered by downstream message/payload assertions).

* chore(nix): refresh pnpm deps hash

* chore(nix): refresh pnpm deps hash

* test(e2e): open settings through the entry settings menu

The home settings entry is now a menu (EntrySettingsMenu): clicking the
gear opens a popover whose "Settings" item opens the full execution-mode
dialog. Update the three specs that assumed a single click opened the
dialog directly to go through the menu trigger + open-details item.

* test(web): drive HomeView context picker through the Lexical helper

The home hero input is a Lexical contenteditable, so fireEvent.change /
reading .value throws "element does not have a value setter". Switch the
MCP+connector first-turn-context spec to setHomeHeroPrompt / homeHeroPromptText
like the rest of the file already does.

* Fix PR review blockers

* Update Nix pnpm deps hash

* Enhance project folder routes with error handling and tests

- Added checks for project existence in GET, POST, and DELETE folder routes, returning a 404 error if the project is not found.
- Updated tests to verify 404 responses for unknown project IDs in folder operations.
- Improved folder metadata handling in project routes.
- Refactored the TabLauncherMenu component for better UI structure and scrolling behavior.
- Adjusted styles for the TabLauncherMenu to improve usability and visual consistency.

* Update ProjectView component and enhance design toolbox localization

- Modified the ProjectView component to include workspacePanelTrack in chat panel width adjustments.
- Updated localization files to add new keys and translations for the design toolbox in English, Simplified Chinese, and Traditional Chinese.
- Enhanced user experience by providing comprehensive tooltips and prompts for design toolbox actions.

* Add browser use prompt launcher

* Cover browser use prompt launcher

* Add design toolbox badge translations

* Refactor ChatComposer and DesignBrowserPanel components

- Removed the design system picker from the ChatComposer component and integrated it into the StagedRunContexts for better context handling.
- Updated the DesignBrowserPanel to include a new function for determining viewport icons and modified the browser use categories to reflect changes in action prompts and titles.
- Enhanced the HandoffButton component with a new feature to copy the project path to the clipboard, improving user experience.
- Added new styles for search input and empty states in design files, enhancing the UI consistency across components.

* Enhance ChatPane and DesignBrowserPanel components with new features and styles

- Added scroll handling features to the ChatPane component, including scrollable state management and improved user experience during chat interactions.
- Updated the DesignBrowserPanel to include new localization keys and improved category titles for better clarity in the browser use prompt.
- Enhanced styles for chat log scrolling behavior, providing a more intuitive interface for users.
- Implemented keyboard shortcuts for tab navigation in the WorkspaceTabsBar, improving accessibility and user efficiency.

* Fix web workspace test hang

* Update styles and functionality for workspace tabs and chat components

- Adjusted CSS for the MAC_WINDOW_CHROME to improve spacing and margins for better layout.
- Enhanced the ChatComposer component to ensure proper tab order and mention handling, improving user experience.
- Implemented keyboard shortcuts for navigating workspace tabs, allowing for more efficient tab management.
- Updated localization strings for clarity in search prompts across multiple languages.
- Improved the HandoffButton component's UI for better visibility and interaction when copying project paths.

* Update visual settings flow

* Refresh Nix pnpm deps hashes

---------

Co-authored-by: open-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com>
Co-authored-by: qiongyu1999 <2694684348@qq.com>
Co-authored-by: Siri-Ray <2667192167@qq.com>
2026-06-03 15:46:22 +00:00
YOMXXXandGitHub 1b4084ced0 fix(desktop): route shell:open-path through explorer.exe on WSL (#1581) (#3298)
On WSL Electron, clicking "Continue in CLI" handed the validated project
directory to shell.openPath, which delegates to xdg-open on Linux.
xdg-open on common WSL installs routes inode/directory MIME through the
default browser via wslu, so the click landed on a Chrome tab showing a
file:// directory listing instead of a native file manager.

Detect WSL via os.release().includes("microsoft"), translate the resolved
POSIX path with `wslpath -w`, and hand the Windows path to explorer.exe so
the host's Explorer opens the folder. Fall back to shell.openPath for
non-WSL Linux, macOS, native Windows, and WSL setups where wslpath or
explorer.exe are missing.

Pull the routing decision into a pure helper (open-path.ts) so the WSL
branch is unit-testable with mocked deps, mirroring the dependency-
injection pattern createDesktopUpdater already uses. Path validation
(validateExistingDirectory, isOpenPathAllowedForProject) stays in front
of the new branch — no change to the allowlist gate.
2026-06-02 07:32:59 +00:00
kamiandGitHub 82ea01836e fix: polish Windows chrome and selected rows (#2169) 2026-05-31 14:44:44 +00:00
b5b975769a fix Windows folder import from project modal (#2863)
Co-authored-by: Lanzhou3 <217479610+Lanzhou3@users.noreply.github.com>
2026-05-26 06:52:07 +00:00
PerishFireandGitHub af66a929bc Fix release updater smoke recovery (#2687) 2026-05-22 16:18:33 +08:00
PerishFireandGitHub b4e94b0534 Harden packaged updater downloads and install handoff (#2677)
* Add managed download package for updater resumes

* fix(download): clear stale pid locks

* test(e2e): harden windows updater resume smoke

* feat(updater): make update downloads silent in ui

* fix(updater): keep install handoff prompt visible

* fix(ci): build platform before download in postinstall
2026-05-22 15:44:28 +08:00
PerishFireandGitHub ec96585a8f fix: harden Windows packaged updater flow (#2595) 2026-05-21 22:32:02 +08:00
PerishFireandGitHub 415c2e9502 fix: clear applied updater install state (#2592) 2026-05-21 21:50:26 +08:00
PerishFireandGitHub 1ef865dd31 fix: defer Windows packaged updater installer (#2575)
* fix: tighten packaged updater flow

* test: prune noisy extended ui coverage

* fix: hide unpublished release artifacts

* test: validate release updater channels

* fix: align prerelease release namespaces

* fix: align packaged updater validation
2026-05-21 19:13:18 +08:00
lefarcenandGitHub b2b94dbde7 feat(desktop): follow OS language in packaged builds (cherry-pick of #2544 into release/v0.8.0) (#2560)
* feat(desktop): follow OS language in packaged builds

Packaged Electron currently shows Open Design in en-US regardless of
the OS language setting, because the renderer's i18n picks its locale
from `navigator.language` and Chromium hard-codes that to en-US unless
the host process intervenes. Browser users and `tools-dev` users are
unaffected because their `navigator.language` already reflects the
OS / browser preference.

This change:

- Adds `applyOsLocaleSwitch(app)` in `@open-design/desktop/main`. It
  reads `app.getPreferredSystemLanguages()[0]` and (when called before
  Electron's `ready` event) points Chromium's `--lang` flag at it, so
  the renderer's `navigator.language` follows the OS. Safe to call
  more than once: `appendSwitch` is a no-op once `app.isReady()`.
- Calls the helper from both Electron entries: `apps/packaged` before
  its own `whenReady`, and `runDesktopMain` for tools-dev parity.
- Forwards the resolved locale through
  `BrowserWindow.webPreferences.additionalArguments` as
  `--od-os-locale=<bcp-47>`, parsed by the preload and exposed at
  `window.__od__.client.osLocale`. The host bridge type
  (`OpenDesignHostClient.osLocale`) is extended accordingly.
- Updates `detectInitialLocale` in `apps/web/src/i18n/index.tsx` to
  read that field as a new step between the existing localStorage and
  navigator fallbacks. Browser/web continues to fall through to
  `navigator.languages` unchanged.

The explicit `osLocale` channel exists in addition to `--lang` because
some `app.getPreferredSystemLanguages()` strings (e.g. `zh-Hant-TW`,
`pt-PT`) need to round-trip through `resolveSystemLocale` to land on
the right supported locale, which Chromium's `navigator.language`
cannot do on its own.

* fix(web): route OS locale read through getOpenDesignHost

The first cut of detectInitialLocale read `window.__od__.client.osLocale`
directly, which trips `tests/host-boundary.test.ts` — that guard test
keeps web source from referencing preload globals by name so the
boundary stays single-source. Switch to `getOpenDesignHost()` from
`@open-design/host`, and rewrite the i18n test to install the host via
`installMockOpenDesignHost` instead of poking the global directly.

* fix(tools-pack): unblock mac packaged build on pnpm workspaces

Two independent issues prevented `pnpm tools-pack mac build --to all`
from completing on a clean macOS workspace, both unrelated to the
desktop OS-locale change in this PR but bundled here because verifying
that change end-to-end required the packaged pipeline to actually
finish.

1. `apps/web/.next/standalone/node_modules/.pnpm/node_modules/<pkg>`
   contained dangling symlinks left by Next's nft trace (e.g. a
   `semver -> ../semver@5.7.2/node_modules/semver` link to a
   `.pnpm/<pkg>@<ver>` directory pnpm never created). The downstream
   `cp { dereference: true }` aborted the whole packaged pipeline
   with ENOENT. Walk every artifact tree before copy and unlink
   symlinks whose target doesn't resolve. Targets that *do* resolve
   stay untouched.

2. Next 16's standalone build under pnpm workspaces does not hoist
   peer-dep packages (react, react-dom, styled-jsx) into
   `<standalone>/apps/web/node_modules`. The downstream
   `web-standalone-after-pack.cjs` audit then does
   `createRequire(server.js).resolve('react/package.json')`, whose
   module walk falls out of the standalone tree and aborts the
   electron-builder phase. Add a `hoistStandaloneNextPeerDeps` step
   for the web standalone artifact only: it locates the
   `<pkg>@<version>` (not peer-resolved sibling) directory under
   `.pnpm` and symlinks it into `apps/web/node_modules/<pkg>`. The
   subsequent `cp { dereference: true }` then writes the real
   directory into the cache so the packaged tree stays self-contained.

Verified by `pnpm tools-pack mac build --to all` succeeding end-to-end
(zip + dmg + app), then `pnpm tools-pack mac install` and
`pnpm exec tools-pack mac inspect --expr` reading the desired
`__od__.client.osLocale` from the packaged renderer.

* feat(desktop): fold encodeURIComponent + manual locale source + pet window from #2554

Three defensive improvements lifted from @Eli-tangerine's parallel
implementation on #2554, kept consistent with the OS-locale chain
already on this branch:

- The argv value crossing main → preload is now wrapped with
  encodeURIComponent / decodeURIComponent so a locale string with `;`,
  `=`, or any other Chromium argv special char round-trips cleanly.
  BCP-47 region tags don't carry those today, but the renderer parser
  no longer has to assume it.
- `setLocale` now also writes `open-design:locale-source = "manual"`
  to localStorage, and `detectInitialLocale` only treats the stored
  locale as winning when that marker is present. An untagged value
  (left over from a future auto-write path, or a stale install) no
  longer pins the app to an old language once the host injects a
  fresh OS locale. Today `setLocale` is the only writer so the marker
  has no behaviour difference yet — this is a defensive net.
- `createDesktopPetWindow` now receives `osLocale` and forwards the
  same `additionalArguments` as the main `BrowserWindow`, so the
  pet renderer's `__od__.client.osLocale` is consistent with the main
  window's instead of being silently undefined.

Co-authored idea credit: changes mirror the locale-piece of
@Eli-tangerine on #2554 — that PR is closing in favour of this one.

Tests: detect-initial-locale gets a new "untagged localStorage value
loses to host locale" case. desktop 62/62, host 13/13, web i18n +
host-boundary 15/15 stay green.

* feat(web): fold onboarding view styles from #2554

Pulls the 747-line addition to `apps/web/src/styles/home/entry-layout.css`
from @Eli-tangerine's #2554 — the visual layer for the global onboarding
flow (`/onboarding` view, Connect / About-you / Design-system steps).
The view itself was already plumbed through `EntryShell.tsx`; this adds
the styling that makes it shippable on v0.8.0.

#2554 is closing in favour of this branch, so the CSS lands here so the
onboarding work doesn't get dropped on the floor.

Co-authored idea credit: @Eli-tangerine — original styling on #2554.

* fix(tools-pack): make hoistStandaloneNextPeerDeps idempotent across builds

Addresses non-blocking review by @PerishCode on #2560: the previous
`if (await pathExists(linkPath)) continue;` guard uses `access()`,
which follows symlinks. A stale symlink from a previous build whose
`.pnpm/<pkg>@<version>` target moved (e.g. after a react/react-dom
version bump that invalidates the workspace-build cache key and forces
a re-run) reports as missing through `pathExists`, then `symlink()`
rejects with EEXIST and the unhandled rejection aborts the packaged
build.

Switch to `lstat` (which does not follow the link) so we can tell
"genuinely empty slot", "real directory left by Next" and "stale
symlink" apart, then unlink stale entries before re-creating. Also
move `stripBrokenSymlinks` ahead of `hoistStandaloneNextPeerDeps` in
`copyWorkspaceBuildArtifactsToCache` so any leftover dangling links
that survived a previous run are cleared before hoist tries to write.
2026-05-21 18:23:20 +08:00
PerishFireandGitHub 526c7f7c26 Fix packaged auto-update release validation (#2565)
* fix: tighten packaged updater flow

* test: prune noisy extended ui coverage

* fix: hide unpublished release artifacts

* test: validate release updater channels

* fix: align prerelease release namespaces
2026-05-21 18:15:53 +08:00
PerishFireandGitHub 899c9fe4d8 Support nightly and preview package identity (#2437) 2026-05-20 19:46:39 +08:00
PerishFireandGitHub 31ca20f2c6 Add packaged update apply observations (#2429) 2026-05-20 19:11:36 +08:00
PerishFireandGitHub 32696d640c fix(desktop): keep the macOS Dock icon when the desktop-pet window opens (#2413)
The desktop-pet companion window calls setVisibleOnAllWorkspaces so it
floats across every Space. By default Electron's macOS implementation
transforms the whole process type between UIElementApplication and
ForegroundApplication while applying that call. On Electron 41 / macOS 26
that round-trip races during the launch burst — the pet window is
created alongside the main window — and the process can stay stuck as an
accessory app: no Dock icon, no menu bar, even though the windows render
fine.

Pass skipTransformProcessType: true so the pet window's all-Spaces
behavior never touches the app's process type. The desktop pet is a
cosmetic companion window; the main window keeps the app a regular Dock
app. The pet still floats on every Space via its alwaysOnTop floating
level.

Fixes #2394
2026-05-20 17:48:01 +08:00
PerishFireandGitHub 15d08d4158 feat: add windows packaged auto update flow (#2362) 2026-05-20 12:56:14 +08:00
PerishFireandGitHub ad37fd30cf Add desktop updater UI flow (#2270) 2026-05-19 21:36:51 +08:00
PerishFireandGitHub 2c128e0e91 refactor desktop host bridge (#2246) 2026-05-19 18:27:05 +08:00
PerishFireandGitHub 4424f08be0 [codex] Add packaged desktop auto-update (#1375)
* Add packaged desktop auto-update

* Handle counted beta nightly update versions

* Refresh desktop auto-update branch for main

* Serialize desktop updater operations

* Refresh auto-update branch for packaged paths
2026-05-19 11:20:05 +08:00
e64f1d8497 fix(desktop): export PDF saves to a file instead of the OS print dialog (#1920)
* fix(desktop): export PDF saves to a file instead of the OS print dialog

The `od:print-pdf` IPC handler called `webContents.print()`, which
opens the printer-first macOS system print dialog. That handler is the
destination of the renderer's `window.__odDesktop.printPdf()` bridge,
so on desktop "Export PDF" felt like a print flow rather than a file
export — from both the PreviewModal share menu (which always uses this
path) and the FileViewer share menu (whose daemon-route fallback lands
here too).

Route the handler through a direct Save-as-PDF flow instead: a native
Save dialog, then `webContents.printToPDF()` straight to the chosen
file — the same shape `exportPdfFromHtml` already uses for the
daemon-backed export path. The flow is extracted into
`savePrintReadyDocumentAsPdf` behind a structural `PrintReadyPdfTarget`
surface that has no `print()` method, so the regression cannot be
reintroduced.

Fixes #1774

Co-authored-by: multica-agent <github@multica.ai>

* fix(desktop): preserve PDF page sizing in print bridge

Co-authored-by: multica-agent <github@multica.ai>

---------

Co-authored-by: multica-agent <github@multica.ai>
2026-05-17 11:26:08 +08:00
4d0ea247a7 fix(desktop): swallow setTypeOfService EINVAL crashes in dev main (#647) (#1298)
* fix(desktop): swallow harmless setTypeOfService EINVAL crashes in dev main

The packaged Electron entry (apps/packaged/src/logging.ts) already
filters the undici "setTypeOfService EINVAL" crash that issue #895
introduced for the prod build, but the dev / source-built desktop
entry was missing the parallel guard. Result: switching settings
tabs in a from-source desktop run could fire a fresh fetch, undici
would try to set IP_TOS on the outbound socket, the kernel would
refuse on certain macOS / VPN configurations, and the rejection
bubbled to Electron's default handler as the "JavaScript error in
the main process" dialog reported in issue #647.

Add the same defensive filter to apps/desktop:

  - isHarmlessSocketOptionError matches only the canonical undici
    shape (syscall name AND EINVAL code). A contradicting code
    (EACCES, EPERM, etc) explicitly fails the match so real bugs
    don't get hidden.
  - The uncaughtException handler logs harmless cases at warn and
    returns silently. For anything else it removes itself from the
    listener list and re-throws via setImmediate, restoring Node's
    default crash path so Electron's native dialog renders exactly
    as it would without this filter.
  - unhandledRejection mirrors the same harmless / fall-through
    split.

The filter is installed BEFORE app.whenReady so it is armed by the
time the renderer fires its first fetch.

The helper is duplicated rather than imported from apps/packaged
because AGENTS.md forbids cross-app private-source imports. The file
header calls out the parallel and notes that the two copies should
stay in sync until the helper is promoted to a shared workspace
package (follow-up); the contract is identical so a regression in
one will surface in the other's test suite.

Tests in apps/desktop/tests/main/uncaught-exception.test.ts mirror
apps/packaged/tests/logging.test.ts: 8 cases pinning the matcher
shape, 2 cases pinning the handler's harmless-log-warn vs
fall-through-rethrow split.

Validated: pnpm guard, pnpm --filter @open-design/desktop typecheck,
pnpm --filter @open-design/desktop build, and pnpm --filter
@open-design/desktop test (14 passed, 10 new).

* fix(desktop,packaged): fail-fast on non-harmless unhandled rejections

The previous unhandledRejection listeners logged non-harmless reasons
and returned, which kept the main process alive after any rejected
promise. A real bug, a failed IPC registration, or any unexpected
async exception was reduced to a console line instead of surfacing
through Node/Electron's default crash path the filter was meant to
preserve.

Both copies now route non-harmless rejections through a parallel
factory (createDesktopUnhandledRejectionHandler /
createFatalUnhandledRejectionHandler) that mirrors the
uncaughtException policy: harmless setTypeOfService EINVAL shapes log
at warn and return, anything else logs at error, removes the
listener, and re-throws via setImmediate. Listener removal happens
before the scheduled throw, so the rethrown reason lands in the
uncaughtException path with no recursion.

Tests cover the harmless branch, the detach + ordered rethrow, and
non-Error / primitive rejection reasons (Promise.reject(42)) which
must fall through. Desktop suite: 13/13, packaged suite: 16/16.
Flagged on PR #1298 by Siri-Ray and the codex P2 review thread; the
two file copies stay in lockstep per the AGENTS.md sync invariant.

---------

Co-authored-by: Nagendhra <nagendhra405@gmail.com>
2026-05-12 16:50:57 +08:00
PerishFireandGitHub a797e079b1 fix(desktop): exit fullscreen before hiding window on macOS close (#1249)
* fix(desktop): exit fullscreen before hiding window on macOS close (#1215)

When a preview is in 演示 → 全屏 mode, the macOS close handler called
window.hide() directly, leaving the OS fullscreen Space orphaned as a
black screen — the window vanished but the Space stayed up.

Extract hideWindowExitingFullscreen as the named invariant ("hide,
but first leave fullscreen so the OS Space tears down with the window")
and route the darwin close handler through it. The hide is deferred
until 'leave-full-screen' fires so we don't race the OS Space teardown.

Bootstraps Vitest on apps/desktop with a single test under
tests/main/hide-window-exiting-fullscreen.test.ts that exercises the
helper through a structural mock — the bug shape is pure logic, no real
Electron window required. Spec was red against a hide-only helper and
green after the leave-full-screen sequencing.

* docs(agents): codify bug follow-up workflow

Distill the spec-first / cheapest-layer / scope-discipline /
invariant-shaped-fix / baseline-diff playbook used recently on #135 and
#1215 into a top-level subsection of root AGENTS.md, framed as a default
action shape with explicit room for case-by-case judgment rather than a
hard rule. Includes a single pointer back to the worked example spec.

* docs(agents): require staged human verification for visible bugs

Add the human-verification gate as a sixth bullet in the Bug follow-up
workflow. UI / platform-native / animation symptoms can pass green specs
and still ship the visible regression — proven by #1215, where the
desktop unit test green-lighted the helper logic but only a side-by-side
buggy-vs-fix run on a real macOS Space proved the black-screen actually
went away.

Reinforces the production-API-only seed constraint while we're there:
source-level backdoors prove a fake flow, not the real one, so they
invalidate the verification.

* fix(desktop): defer hide across the fullscreen-enter transition (#1215)

mrcfps observed on PR #1249 that the close handler only catches windows
already in fullscreen — Electron's enter-full-screen event is async on
macOS, so isFullScreen() can still read false during the OS Space
transition triggered by requestFullscreen(). A close in that window
took the plain hide() path and stranded the same black Space the fix
was meant to eliminate.

Track in-flight fullscreen entry from webContents.enter-html-full-screen
(set) and BrowserWindow.{enter,leave}-full-screen (clear), and surface
it through WindowFullscreenSurface.isEnteringFullscreen. The helper now
parks on enter-full-screen until the OS confirms the Space, then runs
the existing exit-then-hide path.

Adds a regression test ("waits out a fullscreen-enter transition before
exiting and hiding") that goes red against the previous helper.
2026-05-11 17:04:42 +08:00