Imported from tjcccc/myexcalidraw (
AGENTS.md). Install upstream withnpx skills add tjcccc/myexcalidraw. Copyright stays with the author.
myexcalidraw Repository Guidance
Scope
- Build a thin, local-first Tauri shell around the official
@excalidraw/excalidrawReact component. - The first version supports one ordinary local
.excalidrawdocument per window: new, open, save, save as, dirty-state prompts, atomic writes, and lightweight crash recovery. - Keep the upstream Excalidraw editor and its visual language intact. UI changes are limited to what desktop file integration requires.
- Do not add cloud services, accounts, collaboration, tabs, dashboards, custom file browsers, AI features, plugins, or other new scope merely because it seems useful.
Architecture and boundaries
src-tauri/src/: Rust/Tauri lifecycle, native menus/dialogs, validated file I/O, recovery, and window state. Keep commands narrow and serializable.src-tauri/capabilities/: minimum webview permissions. Do not add filesystem, shell, network, or broad plugin capabilities without a concrete need.src/renderer/: React, the embedded Excalidraw component, the typed Tauri adapter, and in-memory document state. It must not import Node.js or perform direct filesystem access.src/shared/: serializable contracts and pure state logic shared by the TypeScript renderer and tests.tests/and Rust module tests: focused behavior coverage for pure document state, native file/recovery services, and trust-boundary validation.
Create only local bundled webviews; reject external navigation and new windows. Validate command window identity, payload sizes and shapes, paths, extensions, dropped-file authorization, and file contents in Rust. The backend owns the active document path; never accept a renderer-supplied arbitrary save destination. Keep filesystem and recovery logic out of the renderer.
TypeScript, React, and Rust
- Keep TypeScript strict and avoid
any; useunknownplus explicit validation at trust boundaries. - Use semicolons consistently. Prefer small, readable modules with explicit responsibilities.
- Keep React state flow one-way: Excalidraw callbacks update the current scene snapshot, desktop commands act on that snapshot, and document transitions remount the editor with official restored data.
- Use the official Excalidraw restore/serialization APIs. Do not create another document schema.
- Keep Rust formatted with
rustfmt, warning-free under Clippy, and explicit about recoverable errors. Avoid panics outside tests. - Do not style or recreate upstream editor controls. Project UI rules are documented in
spec/ui.md.
Commands and completion gates
pnpm run dev: start the Vite renderer and Tauri development app.pnpm run lint: run ESLint and Clippy.pnpm run typecheck: type-check both TypeScript projects and runcargo check.pnpm test: run focused Vitest and Rust tests once.pnpm run build: produce the renderer bundle and optimized native binary.pnpm run package: create native bundles for the current platform.pnpm run dist:mac,pnpm run dist:win,pnpm run dist:linux: create platform artifacts where the host toolchain supports them.
Before declaring work complete, run lint, type checking, tests, and a production build. For release-facing changes, create and launch at least one local package on the current OS, and report other platforms as configuration-only unless they were actually run. Exercise file round trips, image persistence, dialog cancellation, dirty prompts, failed-write preservation, recovery, and normal Excalidraw shortcuts in proportion to the change. Append meaningful decisions, validation results, limitations, and upstream compatibility discoveries to DEVLOG.md.