Commit graph

14 commits

Author SHA1 Message Date
CRT
dece83c3e8 Desktop: custom context menus everywhere, never the browser's menu
One ContextMenu in the design system (keyboard, type-ahead, submenus, check items,
disabled reasons, Shift+F10 / Menu key, viewport placement, light and dark). The
native menu is prevented globally; text fields keep Cut / Copy / Paste / Select all.
Menus on sidebar and portfolio apps, app hero, releases, store art, live art,
reviews, checks, editor fields, catalog, prices, accounts, app folders, ignored.
2026-10-23 08:59:14 +08:00
CRT
9610c9477e Desktop: per-store ignore (hide only the App Store or Google Play side), N ignored show toggle in sidebar and portfolio, Unignore in the app controls; ignore flags sync with the shared app list 2026-10-23 01:35:27 +08:00
CRT
bd316723f5 Desktop v2 design system (design.css tokens for both themes, ui/ds.tsx: PageHeader, Hero, Section, StatTile, Pipeline, StatusPill, EmptyState, Toolbar, Tabs, Dialog, tint and screenshot hooks), app shell: sidebar status dots, frosted top bar, app page Hero with screenshots and the two-store pipeline, pill tabs with blocker counts 2026-10-22 23:12:03 +08:00
CRT
27db41c3f0 Desktop portfolio v2: greeting with what is moving, store-style app cards (rendered screenshots or the icon on its tint), two-store release pipeline, crash sparkline, one next-step button; What changed feed and Fix first queue; Cards / Table switch keeps the old table 2026-10-22 21:24:24 +08:00
CRT
0fb4ce0001 desktop reads everything by itself: one background read scheduler (4 per store, starts spaced per account, App Store Connect X-Rate-Limit slows it below 20 % and pauses at 100 left, backoff with jitter on 429 / RESOURCE_EXHAUSTED, visible app first, one read per key), per-method TTLs over the saved reads, Settings auto-read (on) and interval (15 min, paused while hidden), Refresh all, a refresh icon and 'read 3 min ago' / 'couldn't refresh' per card, writes invalidate, status line with progress and quota; quota reaches the window through ToolResult.quota (cli/lib/quota.ts); Health top issues open with versions, sample stack (health --issue / --signature, read health_issue), Open in Play Console, Copy for AI and likely-cause hints (cli/lib/crash-hints.ts); tests/scheduler.test.ts, tests/quota-crash-hints.test.ts, boot check auto-read case 2026-10-13 23:37:39 +08:00
CRT
89256f1e80 Google API errors as typed findings, never raw JSON: cli/lib/google-errors.ts parses SERVICE_DISABLED (api-disabled: service, Cloud project, console page), PERMISSION_DENIED (no-app-access: which app, Users and permissions), 401 / invalid_grant (auth-revoked) and 429 (quota); health / analytics print one line with the URL, raw text in detail and the log; desktop Health tab: the line, 'Turn it on in Google Cloud' and 'Check again', raw text in a collapsed Details; Portfolio shows a Cloud project blocking several apps once. Findings exit codes are results: the sidecar reports outcome (ok / findings / declined / failed) and the command's own error line; scan / check / validate / health exit 1 with findings show and cache the findings; no bare 'Exit code N' anywhere. tests/google-errors.test.ts, boot check errors cases (api-disabled, scan-findings, scan-failed) (pitfall 57) 2026-10-13 23:20:04 +08:00
CRT
bd3ab20e1d Desktop: never a blank window (frozen-prototype fix, error screens, logs, state migration, boot check)
The signed release showed only its background colour and never started the sidecar. Tauri's freezePrototype
freezes Object.prototype before the bundle runs; d3-color and d3-format (under the visx charts) assign
`constructor` / `toString` on plain objects while loading, which throws on a frozen prototype, so the bundle
stopped before React drew anything. The saved state was not the cause.

- build/freeze-safe.ts: Vite plugin that rewrites those assignments in dependencies into a helper that defines
  the property when the frozen prototype would refuse it
- error boundaries for the window, each screen and each app tab (Copy details, Reload, Reset saved state with a
  backup); public/boot.js shows the same panel when the bundle fails or the window stays empty
- logs/host.log (start, saved state, sidecar start/stop, panics) and logs/webview.log (log_webview), rotated,
  home as ~, keys, tokens and e-mail addresses replaced
- state.json `version` 2 with an explicit 1 -> 2 migration (original kept as state.json.v1.bak), per-entry
  tolerant parsing, partial settings keep their fields, unreadable files kept aside
- folders that are gone: "Folder not found" with Locate... (project_locate) / Remove; portfolio reads skip them
- tools/desktop-boot-check.ts: the built window with the release CSP and the frozen prototype, a mocked host from
  the state fixtures (empty, D1 with folders gone, D3) and the real sidecar, through every screen; in bun run ci,
  the Forgejo CI workflow and the macOS release
2026-10-11 09:36:34 +08:00
CRT
035efa9fa1 No hand-written SVG: visx charts, lucide icons, Mermaid journey diagram
- desktop: Growth chart, Health and portfolio sparklines and the rollout bar drawn with visx (responsive width,
  crosshair tooltip with real values, arrow keys, theme tokens, no animation); icons from lucide-react behind the
  existing Icon names; empty states are lucide icons on token tiles; store marks are generic lucide icons; stars are
  lucide; the brand mark moves to ui/brand.tsx as the one allowed inline SVG
- fixtures: app icons and store art stand-ins are PNGs rendered by tools/fixture-art.ts (lucide on gradients)
- site: icons are lucide's own files in site/img/icons (tools/site-icons.ts, with the ISC licence) shown as CSS masks;
  the journey diagram is rendered from docs/diagrams/journey.mmd by tools/diagrams.ts (Mermaid CLI), with a tall
  variant for phones
- tests/no-handmade-svg.test.ts fails on new inline SVG drawing in apps/desktop/src and site/*.html
- desktop bundle: 598.7 -> 695.5 kB minified, 174.6 -> 206.0 kB gzip
2026-10-11 08:49:30 +08:00
CRT
5d09111528 desktop: Prices, Store art, Growth and App info tabs, exports at the top right and in the command palette, studio and fastlane steps in the first-run guide, fix hints on errors; fixtures, screenshots, tests, UX audit in docs/desktop.md 2026-10-11 07:40:59 +08:00
CRT
15c32d5711 Desktop: portfolio table fits with store-only markers (tighter cells, smaller sparkline) 2026-10-11 04:30:26 +08:00
CRT
7b2cc8da0a Desktop D3 UI: studios and store accounts (health checks with fixes, import apps), one card per app across studios (automatic iOS / Android pairing, manual pair / unpair, links, studio moves), store-only apps read-only, ignore list, portfolio search / studio filter / sort / grouping, collapsible studio sidebar, complete Settings, notifications, fixtures with 3 studios and 5 accounts 2026-10-11 04:15:30 +08:00
CRT
2ef0769730 Desktop D2 UI: design system, portfolio, release timeline, catalog parity, listings, health, reviews, TestFlight, checks, command palette, toasts, first-run guide, en + tr with i18n check, 7:1 theme check, dev fixture mode and screenshot harness 2026-10-11 03:34:47 +08:00
CRT
94d2f3d6ca Desktop: adapt to 0.5.0 (app.platforms, subscriptions, catalog diff), Dependencies polish, ~ for the home folder
- inspect reports platforms, subscription ids and the catalog each store should sell; app identity
  and parity follow app.platforms and per-item platforms; catalog.diff joins the JSON methods
- Portfolio: one Platforms column, compact catalog, paths truncated and shown with ~; the confirm
  dialog and run logs show ~ instead of the home folder
2026-10-11 02:15:48 +08:00
CRT
61a1e832a0 Desktop app shell (apps/desktop): Tauri 2 + React 19 around the storebound sidecar
- Rust host: spawns storebound serve --stdio with fixed args, hands over a per-session secret,
  mints confirm tokens only after a native dialog showing the summary and the dry run
- every app command re-checks window label and page origin; one capability (main window, app
  commands + event listen only, no plugin API in the webview); strict CSP; tests/security.rs pins it
- store keys picked in native dialogs, kept in the OS keychain, passed per call in memory only
- plugins: shell (Rust only), single-instance, deep-link storebound://, window-state, opener,
  dialog, notification, updater (placeholder endpoint and key until signing), process
- app-centric UI: Portfolio, App (Releases, Catalog, Listings, Health, Reviews, TestFlight),
  App folders, Accounts, Dependencies, Settings; light / dark with the storebound.dev tokens,
  reduced motion, home folder shown as ~
- macOS menu: Cmd+Q quits, Edit menu, Window menu keeps the main window; Linux DMABUF fix
- Bun workspace (npm files unchanged), ci runs desktop typecheck, build, cargo test and clippy;
  scrub covers home paths; docs/desktop.md (protocol, safety, dependency sources and licenses)
2026-10-11 01:57:33 +08:00