- specs/: Apple's App Store Connect OpenAPI 4.5.1 and the Google discovery docs for androidpublisher v3 and
playdeveloperreporting v1beta1, pinned with URL, date and SHA-256 (specs/SOURCES.json)
- tools/gen-api.ts: one row per operation (cli/api/apple.gen.ts 1303, cli/api/play.gen.ts 170), a scan of which
operations the commands already call (cli/api/wrapped.gen.ts) and docs/api-coverage.md; CI checks freshness
- cli/api/client.ts + types.ts: generic URL / parameter building, retries with Retry-After, pagination, types derived
from the rows; auth reuses ascJwt and the Play service account
- cli/api/gate.ts: GET runs, writes dry unless --yes in a TTY, owner-only operations need the id typed, nothing
written under MCP or serve; MCP gets the read-only api_get
- storebound api list | coverage | apple|play <op|METHOD path>; skill store-api, README, CHANGELOG, tests
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
Desktop icons move from lucide to Phosphor (@phosphor-icons/react, per-icon imports, regular weight; fill for the
active nav item, notices and rating stars). The site's icons and the fixture art use Phosphor's own files from
@phosphor-icons/core. App Store and Google Play are shown with their marks from simple-icons (CC0 data), vendored
unchanged by tools/site-icons.ts and rendered as a mask in the neutral text colour next to the store's name; the
trademark note is in docs/desktop.md and the site footer. lucide-react and lucide-static removed. The
no-hand-written-SVG guard allows only the vendored files (byte-equal to their packages) and per-icon Phosphor
imports. Site stylesheet ?v= bumped.
- 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
- 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)
- tools/gen-adapters.ts writes the Claude Code plugin + .mcp.json, Codex plugin, Gemini CLI
extension + GEMINI.md, AGENTS.md, Copilot instructions and a Cursor rule from skills/ and
docs/agents-core.md; --check fails on stale files
- tests for adapters, MCP tools and JSON-RPC, validate rules, ASO, release notes, privacy
manifest, release helpers, install merging, scrub
- bun run ci: adapters check, tests, typecheck, secrets / personal data scrub
- 0.2.0