Work as a senior product engineer and finish the application in this specification. This is a real application, not a mockup. Create the complete source tree, configuration, migrations or schemas, working UI, persistence, error handling, and tests. Do not leave stub handlers, simulated production data, TODO features, inert buttons, or invented successful test results.
Start by inspecting the workspace and available tools. Choose compatible maintained dependency versions and pin them in a lockfile. Write a short implementation plan and an acceptance checklist, then implement and run the work without stopping after planning. Use stages to manage complexity, but carry every required stage to completion. If context runs low, save progress and remaining acceptance checks in a local handoff document and resume from it. Ask only about decisions that cannot safely be inferred.
Keep modules small and put domain logic outside presentation components. Validate inputs at trust boundaries, handle cancellation and failures, preserve user data, and provide clear recovery actions. Include keyboard access, labelled controls, visible focus, useful empty/loading/error states, sensible contrast, and reduced-motion support. No advertising, subscriptions, analytics, hidden cloud dependencies, or remote executable loading.
Before finishing, run the compiler/type checker, linting, unit/integration tests, and a production build. Add real workflow tests for the acceptance checklist and run them against the built application where possible. Fix failures and repeat affected checks. Report exact commands, actual results, any environment-blocked checks, setup instructions, and remaining limitations. Never call an unfinished or untested feature complete. Include a README explaining architecture, development, packaging, data locations, permissions, and recovery. Use clean generated sample data only in explicit tests and previews.
Build {{app_name}}, a focused private Gmail desktop client inspired by Clarity Mail. Use Electron, React, strict TypeScript and a local mail cache. Make a clean dark interface with mailbox list, independently scrollable messages/reader, search, accounts and a compose window; use {{accent_colour}} as the accent. This is a real Gmail client with real authentication and mail operations, not a static inbox demo.
Implement desktop Gmail first. On compatible Linux systems, use GNOME Online Accounts through the user's session bus. Provide an optional system-browser OAuth Authorization Code + PKCE fallback with random state, a bounded loopback callback, token refresh and revocation. Desktop apps are public clients: no embedded client secret and no Google password form. A developer registers their own OAuth public client ID and consent screen. Explain Gmail API permissions and possible provider verification requirements; never copy existing project IDs, signing keys or credentials. Keep the app useful if the selected auth integration is unavailable by showing a clear setup error.
Trust boundary: tokens live only in the privileged host. Use OS-backed Electron safeStorage when secure; if Linux reports a basic-text backend, keep tokens only in memory rather than pretend encryption. Sandboxed renderer, context isolation, disabled Node integration, restrictive CSP, navigation restrictions and narrow validated typed IPC. Local mail content/cache remains user-only but is not automatically encrypted: explain full-disk encryption for offline confidentiality. Never log tokens, private messages or authentication headers.
Mail engine: initial complete history sync, not only new messages; paged mailbox data and on-demand full body/attachment fetching. Incremental sync must handle deletion, changed labels, invalid cursors and expired tokens. On the system-account path, implement Gmail IMAP/SMTP with OAuth, UID/mod-sequence updates and IDLE plus periodic fallback. Prevent duplicate notifications after restart. Support account switching, search, compose/send/reply/forward, attachments, drafts, archive, labels, read/unread, star, move to recoverable Trash, spam marking and undoable actions. Respect transport errors and API limits with retries/backoff; never display an unsent message as sent.
Local classification is explainable and correctable: Gmail Spam/high-confidence scam signals to Spam; explicit verification-code subjects with actual code tokens to Codes; failed payments/account alerts and critical security warnings to Important; completed payments to Receipts; routine provider notices to Google/Microsoft; marketing/list headers to Promotions; routine service updates to Updates; trustworthy direct human mail to Personal. Read Important/Personal inbox mail older than seven days moves to Old Inbox except explicitly kept messages. Apply labels consistently without deleting mail. Codes are never automatically deleted. Add a Keep in Inbox override and classification reasons. Notify only newly arrived Important messages in Inbox, not spam, bulk mail, old resync results or repeats.
Reader safety: sanitize HTML and remove active scripts, forms, event handlers and frames; avoid unsafe styles and remote tracking pixels. Treat attachment names/URLs as untrusted, block path traversal, and use explicit downloads/opening. HTTPS images load only under the documented reader policy without leaking referrers; resolve Content-ID inline images locally. External links go to the system browser. Include malicious-message security fixtures.
Keep a lightweight tray process and optional quiet autostart, with an obvious Quit action. Do not add Android to this build; it can be a separate fully specified follow-up instead of a fake cross-platform promise.
Acceptance: test OAuth state/PKCE and token boundary, classification precedence, no automatic code deletion, notification deduplication, safe HTML/attachments and sync cursor recovery using synthetic mail fixtures. With an explicitly supplied test Gmail account, verify sign-in, historical sync, send/reply/draft, archive/Trash/undo and reconnect. Never send real mail or relabel a real mailbox without the operator's explicit test authorization. If no test account exists, report live integration as unverified while still running contract/fixture tests. Provide exact consent-screen/developer setup, local data deletion/revocation and build/package instructions.
Paste this into your preferred AI assistant. Review its output before running it.