openpencil/desktop/AGENTS.md
Danila Poyarkov 55d8c57822
feat(desktop): show updates in a Software Update window (#936)
* refactor(app): share Markdown rendering outside chat

Move the vue-stream-markdown wrapper, inline code, token mapping, and
styles out of chat into components/markdown and theme/markdown, so other
surfaces can render Markdown without importing chat components. A density
attribute selects the compact chat styles or a comfortable reading size,
and Shiki highlighting is opt-in. ChatMarkdown keeps its streaming render
key and wraps the shared component.

* refactor(ui): extract AppProgress from the toast

The toast drew its own progress track, fill, and label. Move them into
AppProgress in ui/feedback, built on Reka's Progress so the bar reports
its value and indeterminate state, with an accent tone for panels and a
current-colour tone for coloured surfaces. ToastProgress becomes the
shared ProgressAmount. AppPlaceholder also accepts an h1 label for
placeholders that stand for a whole window.

* feat(desktop): show updates in a Software Update window

The update prompt passed the release's CHANGELOG section to the native
confirm dialog, which cannot format Markdown or scroll, so the 0.15.1
notes showed raw headings and pushed the buttons off screen.

When the main window finds an update it now opens a small `updater`
webview loading its own `updater.html` entry, which never boots the
editor. The window renders the notes with the shared Markdown component
in a scrolling box and links to the full release page.

Installing is split into stages. The download shows progress and can be
cancelled; Tauri cannot abort it, so Cancel detaches and a later Install
reuses the running download. On macOS and Linux the update then installs
and the window offers Restart Now or Later. A restart, and on Windows the
installer that quits the app, first asks the editor window to run the
same unsaved-documents approval as Quit. Failed checks, downloads,
installs, and restarts keep the release visible and can be retried. The
window's capability grants only update, restart, close, and link
opening.

Closes #743

* fix(desktop): stop waiting for a restart reply from a closed editor

The Software Update window waited for the editor's answer with no bound,
so an editor closed mid-request left Restart Now, and the Windows
install, stuck. Treat the editor window's destruction as approval: it
ran its own unsaved-changes prompt and holds no documents. A timeout
would instead fail people still answering that prompt.
2026-10-06 14:57:31 +00:00

2.8 KiB

Desktop (Tauri v2)

Check desktop/Cargo.toml, desktop/capabilities/**, and desktop/tauri.conf.json before adding desktop capabilities. Release versions are also set in desktop/tauri.conf.json and desktop/Cargo.toml (tools/AGENTS.md, Releases).

  • File system and shell permissions must be configured explicitly; a vague "Internal error" save failure usually means a missing permission.
  • Dev tools: add or use a menu item to toggle them; do not rely on keyboard shortcuts.
  • desktop/src/credentials.rs stores secrets in the native system credential store; failures must surface, never fall back to browser or plaintext storage (src/AGENTS.md, Settings).
  • ACP and harness process changes require checking desktop/capabilities/**.
  • The fs scope allows documents anywhere but denies, in the global fs:scope, every place where a written file would run, and requireLiteralLeadingDot keeps hidden files out of ** on every platform; a new write path must not reopen either (tests/e2e/native/fs-scope.spec.ts).
  • A shell:allow-spawn entry pins the whole command line: no "args": true, and a Windows .cmd shim runs through its own cmd-<name> entry with fixed /c <name> … arguments, which resolvePlatformCommand selects (tests/engine/tauri/command.test.ts).
  • The Software Update window is a second webview labelled updater that loads updater.html (src/updater.ts), never the editor's index.html; its own capability, desktop/capabilities/updater.json, grants only checking, installing, restarting, closing, and opening links. It owns no documents, so before a restart or a Windows install it asks the editor window over updater:restart-request to run the Quit approval (src/app/shell/updater/approvals.ts, tests/app/shell/updater/session.test.ts).
  • Never click Install in a tauri dev build: the updater unpacks the release next to the running binary, which there is desktop/target/debug.
  • desktop/generated/menu.json is produced by bun run generate:tauri-menu from src/app/shell/menu/schema.ts; do not edit or import it directly.
  • Run bun run generate:icons --target desktop before direct Cargo checks; native icons are generated, not committed.
  • build_fig_file performs .fig export on desktop; the browser path uses fflate (packages/fig/AGENTS.md).
  • The embedded WebDriver plugin compiles only with the native-test Cargo feature and must never be enabled in development or production binaries. Native tests use bun run test:native (tests/AGENTS.md).
  • openpencil:// links are parsed in desktop/src/deep_link.rs: open queues files through take_pending_open, join queues validated room IDs through take_pending_rooms; second launches forward their link arguments through the single-instance handler (deep_link unit tests).