Commit graph

27 commits

Author SHA1 Message Date
CRT
dfc6362335 boot check: the portfolio with a Play page 404 counts no live version
Some checks failed
ci / gate (push) Successful in 2s
ci / ci (push) Successful in 1m59s
ci / windows (push) Has been cancelled
ci / linux (push) Has been cancelled
ci / acceptance (bun, 22, ubuntu-22.04, Linux, bun) (push) Has been cancelled
ci / acceptance (bun, 22, windows, Windows, bun) (push) Has been cancelled
ci / acceptance (node20, 20, ubuntu-22.04, Linux, node) (push) Has been cancelled
ci / acceptance (node20, 20, windows, Windows, node) (push) Has been cancelled
ci / acceptance (node22, 22, ubuntu-22.04, Linux, node) (push) Has been cancelled
ci / acceptance (node22, 22, windows, Windows, node) (push) Has been cancelled
ci / dev (push) Has been cancelled
ci / record (push) Has been cancelled
2026-11-08 03:26:22 +07:00
CRT
98e123f403 public MCP: the bare host answers MCP (POST /) and names the connect URL (GET /) 2026-11-08 03:14:37 +07:00
CRT
e100001017 desktop: boot check finds unsaved marks on the sub views; neutral next-step lines before a read
Some checks failed
ci / gate (push) Successful in 3s
ci / linux (push) Has been cancelled
ci / ci (push) Has been cancelled
ci / windows (push) Has been cancelled
ci / acceptance (bun, 22, ubuntu-22.04, Linux, bun) (push) Has been cancelled
ci / acceptance (bun, 22, windows, Windows, bun) (push) Has been cancelled
ci / acceptance (node20, 20, ubuntu-22.04, Linux, node) (push) Has been cancelled
ci / acceptance (node20, 20, windows, Windows, node) (push) Has been cancelled
ci / acceptance (node22, 22, ubuntu-22.04, Linux, node) (push) Has been cancelled
ci / acceptance (node22, 22, windows, Windows, node) (push) Has been cancelled
ci / dev (push) Has been cancelled
ci / record (push) Has been cancelled
2026-10-24 13:06:42 +08:00
CRT
eac6388705 desktop: five sections by job (Release, Store page, Revenue, Players, Health), Game services view, sidebar by attention
- app view: 12 tabs become 5 sections, each with a header (what it is for, the one next step from state
  already read) and its sub views in a segmented control; 1-5 jump, Ctrl+Shift+[ ] cycle, Ctrl+K and the
  context menu list sections and sub views; old tab ids, section and section/sub links all resolve
- Players > Game services (games only): both stores, one row per leaderboard / achievement with its
  languages and each store's state, Game Center locale map, Play API-disabled state with the console plan
- games status --json: items, localeMap, playApiDisabled; inspect summary: games
- sidebar: apps grouped by attention / in progress / live / not on a store, one status line each, studio
  filter, workspace as a footer icon row
- boot check opens places like a person (section, then sub view)
2026-10-24 13:06:42 +08:00
CRT
9a01763e73 Desktop boot check: quota row match as plain text
Some checks failed
ci / gate (push) Successful in 2s
ci / ci (push) Failing after 59s
ci / linux (push) Successful in 4m3s
ci / windows (push) Successful in 3m38s
ci / acceptance (bun, 22, ubuntu-22.04, Linux, bun) (push) Successful in 30s
ci / acceptance (node20, 20, ubuntu-22.04, Linux, node) (push) Successful in 1m28s
ci / record (push) Successful in 11s
ci / acceptance (node22, 22, ubuntu-22.04, Linux, node) (push) Successful in 1m26s
ci / acceptance (bun, 22, windows, Windows, bun) (push) Successful in 27s
ci / acceptance (node20, 20, windows, Windows, node) (push) Successful in 5m11s
ci / acceptance (node22, 22, windows, Windows, node) (push) Successful in 5m24s
2026-10-23 10:47:39 +08:00
CRT
d2202b930b Desktop boot check: the reader's quota row uses the short wording
Some checks are pending
ci / gate (push) Waiting to run
ci / ci (push) Blocked by required conditions
ci / acceptance (bun, 22, ubuntu-22.04, Linux, bun) (push) Blocked by required conditions
ci / acceptance (bun, 22, windows, Windows, bun) (push) Blocked by required conditions
ci / acceptance (node20, 20, ubuntu-22.04, Linux, node) (push) Blocked by required conditions
ci / acceptance (node20, 20, windows, Windows, node) (push) Blocked by required conditions
ci / acceptance (node22, 22, ubuntu-22.04, Linux, node) (push) Blocked by required conditions
ci / acceptance (node22, 22, windows, Windows, node) (push) Blocked by required conditions
ci / linux (push) Blocked by required conditions
ci / windows (push) Blocked by required conditions
ci / record (push) Blocked by required conditions
2026-10-23 10:46:49 +08:00
CRT
f8c76c607e Desktop boot check: the dry-run preview is accepted whenever it shows, also during waits
Some checks failed
ci / gate (push) Successful in 2s
ci / ci (push) Failing after 57s
ci / linux (push) Successful in 3m47s
ci / windows (push) Successful in 4m14s
ci / acceptance (bun, 22, ubuntu-22.04, Linux, bun) (push) Successful in 41s
ci / acceptance (node20, 20, ubuntu-22.04, Linux, node) (push) Successful in 1m17s
ci / record (push) Successful in 12s
ci / acceptance (node22, 22, ubuntu-22.04, Linux, node) (push) Successful in 1m24s
ci / acceptance (bun, 22, windows, Windows, bun) (push) Successful in 29s
ci / acceptance (node20, 20, windows, Windows, node) (push) Successful in 5m53s
ci / acceptance (node22, 22, windows, Windows, node) (push) Successful in 5m48s
2026-10-23 10:44:54 +08:00
CRT
8f3912d13e Desktop boot check: say why a tab could not be opened
Some checks failed
ci / gate (push) Successful in 3s
ci / ci (push) Failing after 1m9s
ci / linux (push) Successful in 4m11s
ci / windows (push) Successful in 4m19s
ci / acceptance (bun, 22, ubuntu-22.04, Linux, bun) (push) Successful in 31s
ci / acceptance (node20, 20, ubuntu-22.04, Linux, node) (push) Successful in 1m16s
ci / record (push) Successful in 9s
ci / acceptance (node22, 22, ubuntu-22.04, Linux, node) (push) Successful in 1m9s
ci / acceptance (bun, 22, windows, Windows, bun) (push) Successful in 29s
ci / acceptance (node20, 20, windows, Windows, node) (push) Successful in 5m42s
ci / acceptance (node22, 22, windows, Windows, node) (push) Successful in 5m53s
2026-10-23 10:36:38 +08:00
CRT
addb4e8ccc Desktop boot check: tabs opened like a person (the More menu when a tab is not in the row); the fake host answers window dry runs like the Rust host (dryRun forced), art.pull preview dry run
Some checks failed
ci / gate (push) Successful in 2s
ci / ci (push) Failing after 1m9s
ci / linux (push) Successful in 4m19s
ci / windows (push) Successful in 3m48s
ci / acceptance (bun, 22, ubuntu-22.04, Linux, bun) (push) Successful in 30s
ci / acceptance (node20, 20, ubuntu-22.04, Linux, node) (push) Successful in 1m19s
ci / record (push) Successful in 10s
ci / acceptance (node22, 22, ubuntu-22.04, Linux, node) (push) Successful in 1m9s
ci / acceptance (bun, 22, windows, Windows, bun) (push) Successful in 29s
ci / acceptance (node20, 20, windows, Windows, node) (push) Successful in 5m41s
ci / acceptance (node22, 22, windows, Windows, node) (push) Successful in 5m25s
2026-10-23 10:31:40 +08:00
CRT
8385db2dad Desktop boot check: accept the in-app dry-run preview before the native confirm 2026-10-23 10:25:26 +08:00
CRT
68ac313114 Desktop boot check: scroll live art tiles one by one and wait for each lazy thumbnail 2026-10-22 23:58:45 +08:00
CRT
dd8090d41b Desktop boot check: v2 markup (scan finding guideline pill, catalog screen root, lazy live thumbnails scrolled into view) 2026-10-22 23:47:29 +08:00
CRT
d6b97a362b desktop boot check: match the submit dry run by its fields, not the exact JSON (the call carries platform since the macOS support; 0.8.14's Mac build stopped on it)
Some checks failed
ci / gate (push) Successful in 4s
ci / linux (push) Has been cancelled
ci / ci (push) Has been cancelled
ci / acceptance (bun, 22, ubuntu-22.04, Linux, bun) (push) Has been cancelled
ci / acceptance (bun, 22, windows, Windows, bun) (push) Has been cancelled
ci / acceptance (node20, 20, ubuntu-22.04, Linux, node) (push) Has been cancelled
ci / acceptance (node20, 20, windows, Windows, node) (push) Has been cancelled
ci / acceptance (node22, 22, ubuntu-22.04, Linux, node) (push) Has been cancelled
ci / acceptance (node22, 22, windows, Windows, node) (push) Has been cancelled
ci / windows (push) Has been cancelled
ci / record (push) Has been cancelled
2026-10-20 03:29:59 +07:00
CRT
f0cd8dc670 tests copy the demo app as git has it: the example's gitignored .storebound/, renders, frames and video of a local checkout stay out of the temp copy (edit.test.ts failed on a local .storebound/, the boot check's store art case opened a local ios69 render instead of its pulled Play shot) 2026-10-14 06:10:39 +08:00
CRT
16eeab0e74 desktop boot check: the Store art tab's live thumbnails are read on demand (art live), so its 'Live store art not read yet' is not a missed background read 2026-10-14 05:35:59 +08:00
CRT
b5758b3ebb store art from the live stores: storebound art pull (App Store screenshot sets and previews per locale and display type from imageAsset.templateUrl at the original size, the App Store icon from the newest build or the public artwork; per Play language icon, feature graphic, phone / 7" / 10" / TV / Wear screenshots as the =s0 originals checked against Play's sha256) into store/renders with pulled.json (sha256, store, URL host, store checksum); upsert (a re-run changes nothing, differing local files kept unless --force, the upload's file of a slot compared: Play .jpg, App Store .png, the App Store icon as a picture); onboard runs it; apple screenshots / previews and play images see unchanged pulled files as the store's own; check: render sources are notes with pulled art; local renders check: pulled files pass, store-empty sets not demanded; art live / thumb / replace; desktop Store art tab: live thumbnails per store, language and set (same / differs / not pulled), Pull from stores, store-only apps read-only, Replace with a file (image_pick, art.replace) in the lightbox and the art editor; boot check store art case; tests/art-pull.test.ts; console parity 76 rows (57 complete, 19 with the reason); store-screenshots skill (pull first for live apps), pitfall 59 2026-10-14 05:25:37 +08:00
CRT
0882522d15 CI green on a loaded shared machine: browser suites (now also glyph-ligatures and feature-fit, through the shared launch helper) in one dedicated shard started first at concurrency 2; timeouts scaled by load ÷ cores (tests/helpers/load.ts, max(1-, 5-min average), capped at 5x, logged) for browser tests, waits, launch/close, the other shards' default and the desktop boot check; one retry for a browser test that timed out while the factor was above 2, listed as 'retried under load' in the CI summary, never for an assertion failure; the six-type App Privacy walk no longer dumps every step (the --debug-dump check walks two types), wait timeouts print per-line times; play-edit-lock checks reads in flight instead of wall time; tests/load-retry.test.ts 2026-10-14 05:21:15 +08:00
CRT
40f899cb16 desktop editors: edit in place what App Store Connect and Play Console let the owner edit (listings per language for both stores with live counters and the check / scan rules, store details, App info, age rating, App Review, Play store settings, Data safety and App Privacy answers, promotion blocks, catalog names / prices / offers, TestFlight information, scene order); storebound edit (project.edit) saves into the config by path keeping comments and formatting, the listing files and the review contact, dry run with the diff and the checks first; Apply shows each store's dry run in the window; unsaved edits survive tab switches with undo / redo; tests/edit.test.ts, apps/desktop/tests/edits.test.ts, boot check editor case 2026-10-14 00:37:08 +08:00
CRT
186affd84f Play edits under a machine-wide per-package lock (parallel reads of one app no longer delete each other's edits; a read whose edit was deleted is redone once, writes are not); a store that failed to read is 'Couldn't read Google Play' and keeps its last good releases with 'couldn't refresh'; stores on different versions: neutral 'Current · Play x · App Store y' header and each lane its own state, 'Not on this store' only without a record; Play status decided from the public store page's live version (Live / In review / In review (live: x) / managed publishing / Rolling out / Halted / Draft; only a network failure says 'Couldn't check the store page', with the last known answer and its time); tests/play-edit-lock.test.ts, recorded page fixture, boot check auto-read cases (pitfall 58) 2026-10-14 00:26:17 +08:00
CRT
961eeb5c17 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
4877d950fb 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
5df8f1807a Play 'Live' only when the public store page proves it: play status checks https://play.google.com/store/apps/details?id=<pkg> (no auth, 4 s timeout, cached 5 min; publicPage in the JSON), a completed production release with a 404 page is 'Sent to Google (in review or not yet published)', 200 is live for the first release or when the page shows the versionName, otherwise 'Released to production (Google may still be reviewing)', offline is unknown; new phases sent / released in the desktop Releases tab, Portfolio, release status | plan; versions matched across the stores without trailing .0 parts (App Store 1.0 and Play 1.0.0 are one row and one train, each side shows its own string); tests/play-public-version-match.test.ts, desktop boot check release-state cases (page 404 and 200) (pitfall 56) 2026-10-13 20:46:48 +08:00
CRT
94745c9f39 Onboarding live apps without owner questions for what the stores and the code prove: storebound onboard imports the live products and subscriptions with USD / base prices (catalog diff clean), contact values, the App Review contact and demo account (credentials.json, masked), sign-in for review from Apple's review detail and auth code, and the account deletion page from the app's site; App Store keywords count characters (live fields up to 265 bytes accepted); validate accepts the 6.5-inch iPhone set and Play's default-language graphics fallback; Play Reporting API off gives the project's enable link and apps list falls back to local apps; accounts default <profile>; store-only apps (apps add --store --app-id) shown read-only in the desktop (pitfalls 43-52) 2026-10-13 07:25:01 +08:00
CRT
3c9517f7fd One product per machine: the CLI and the desktop app share one version, the store accounts and the app folder list
- one version: package.json's version is the desktop app's too (desktopVersion removed); tools/desktop-version.ts
  keeps the plugin manifests and the app's copies equal, desktop-release publish refuses another version, release
  order app first then npm publish; the unpublished desktop 0.1.0 candidate is noted in the docs and CHANGELOG
- storebound desktop installs (per user, no admin: macOS DMG -> /Applications or ~/Applications, Windows NSIS /S,
  Linux AppImage + .desktop with the storebound:// handler), updates an older app, notes a newer one (downgrade only
  with --force), asks once ([Y/n], --yes, exit 3 without a terminal), opens on the folder; --dry / --json / --download;
  the install steps are pure plans (cli/lib/desktop-install.ts); the version's own manifest dl/<version>/latest.json
- credentials: one store, the CLI's credential profiles in ~/.storebound/credentials; the desktop writes and reads
  them (profiles.rs, files 0600), moves old keychain accounts into profiles on first start, shows profiles the CLI
  made; precedence env > named profile > project file > default profile; config `account`, "account" in the
  project's credentials.json; storebound accounts list | import (dedup by key id / service account e-mail, key files
  copied 0600, project file keeps keystore and review contact, backup, --dry, never prints values) | use
- app folders: one list ~/.storebound/projects.json shared by the desktop (registry.rs), storebound desktop,
  apps folders | add | remove, ws init and ws without a workspace file
- desktop: notice when a folder pins another storebound version; storebound-desktop --version
- tests: version drift, desktop decisions and per-OS plans, credential precedence and import, registry (TS + Rust),
  keychain migration and profile round trip (Rust), boot check with old keychain state and the new shared state
2026-10-13 06:17:37 +08:00
CRT
3b1852bb5b ci speed: desktop boot check runs its cases in parallel (one browser, killed at the end; a page per case; condition waits instead of fixed sleeps: element, text or a quiet window of host calls and DOM); shots capture / render close the browser with a 3 s cap, then kill it; console engine waits injectable for tests (WAITS / engineWaits: poll rounds, a missing step ends once its loaded page stays quiet, team switch settle, field-miss grace), fillPage looks up each data type's dialog once per round and skips dialog sections when no dialog is open; browser tests run 4 at a time per file (testScope().concurrent with a scope per test, --max-concurrency in ci), 20 ms rounds; capture-web counts boots per test and runs its browser tests concurrently; console-session / -persist Chrome tests concurrent; recorded test timings smoothed (mergeTimings) so one loaded run does not skew the shard split 2026-10-13 02:22:25 +08:00
CRT
f60919b632 desktop: Releases > Send for review (App Store submission state, builds by number, Submit / Resubmit / in-app purchases; Play versionCodes by number, Send to production, managed publishing, console plans for countries and Send changes for review), plan panel before every owner dialog with streamed progress; App info console steps for every console plan form with verify; Catalog price-change owner actions and the declined state; Data safety deletion answer; TestFlight create missing groups; Android SDK in Dependencies; upload progress in job toasts; boot check send-for-review cases on D1 and D3 state 2026-10-12 12:08:43 +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