confirm() prints 'declined: <reason>' and exits 3 whenever the answer is no or nobody can answer (not a
terminal without --yes, serve without the owner's dialog), so no command reports success after declining.
flow run stops at such a step with 'step N declined: <reason>' (status declined), never ok. flow run
--apply --yes passes --yes to write steps only; --yes without --apply is refused. Pitfall 24.
apple build and play build run build.prebuild (or apple.prebuild / play.prebuild) first, once per flow run;
--no-prebuild skips it, --dry only prints it. A Capacitor project's copied public/index.html must then be newer
than the last source commit and <webDir>/index.html, else the build stops (--allow-stale-web overrides). check
warns when stale without a prebuild; the build output and dry plan show the web bundle's sha256 and mtime.
The Capacitor project is also found in a monorepo (apps/native etc.); several ask for play.build.dir /
apple.build.*. Pitfall 23.
A phone-only project aborted with 'no sevenInchScreenshots'. Play requires the 512 icon, the 1024x500 feature graphic and at least 2 screenshots (Play Console Help answer 9866151). play images uploads what exists and prints an info line for missing optional sets; play.tablets true makes missing tablet sets an error in shots render/check/gallery, validate and play images. Pitfall 19.
Google's account widget and cookie rotation frames (accounts.google.com /
ogs.google.com) on a signed-in Play Console no longer count as a sign-in
page. Each detection logs its rule and URL; heartbeats name the page; a
copied Chrome session that lands on a sign-in URL is said plainly; the
sign-in wait gets a watchdog dump, and --debug-dump up to 3 dumps.
Fixtures and tests for the chooser and home with the widget frames and a
top-level accounts.google.com page; pitfall 16.
A real run (sanitized debug dump) showed why the walk stopped after Next:
the data types step is the same "Data Collection" dialog (URL unchanged),
and each checkbox's accessible name is its label run together with its
help text ("NameIncluding first or last name"). Some labels also differ
from Apple's help page ("Purchases", "Other Data").
- labelNames: the exact name, then the label as a prefix that ends where
the help text starts (no lowercase letter follows), so "Name" never
matches "Phone Number...", "Head" never "Health...", "Contact" never
"Contacts...". Used for the data types and the purposes.
TYPE_ALIASES maps Purchase History / Other Data Types to the console's
labels.
- Dialog per step: a section's dialog is also found as the one visible
dialog with a heading of that name.
- Every click and check is bounded (ACTION_MS, 10 s; the scan test now
also rejects clicks without a timeout).
- The flow fixture mirrors the real dialog's structure (dialog/h2 title,
group h3s, input name = Apple's enum, <label> with label + help <p>s,
Save disabled until a type is ticked); no data from the dump. A test
checks every Apple type matches exactly one real-style checkbox.
- Pitfall 15.
Publish is still never clicked; unknown steps still get the watchdog dump.
Play content rating (IARC): storebound now clicks Save draft, then Next,
on each page, like App Privacy's draft saves. Google keeps one draft per
app and IARC gets nothing before Submit, which stays the owner's click.
FORM_BUTTONS, the flow gate (AUTO_DRAFT_SAVE), the console-autofill
skill and the guardrail test are updated; the test answers the open
questions as the owner and checks that Submit on the Summary is never
clicked.
App Privacy stopped at "now click Get Started yourself" and every page
asked the owner to click Next. The owner should not click what
storebound can safely do.
- Every button of every console form is classified (navigation,
draft-save, final-submit) in FORM_BUTTONS (cli/lib/console-forms.ts),
citing Apple's and Google's help pages. A scoped flow gate
(flowAllowed) lets navigation through; the generic click gate stays
absolute for field clicks.
- App Privacy: Get Started, Edit next to Data Types (never the Privacy
Policy Edit), each data type / "Set Up <type>", Next, and the Save
inside the questionnaire dialogs (a draft: Apple publishes only after
Publish, per "Manage app privacy"). Each type's dialog may be one page
or purposes > Next > linked > Next > tracking > Save. It ends with
"review the summary, then press Publish yourself". Publish is never
clicked.
- Play content rating and target audience: Next by itself. Save draft,
Submit, the final Save, Create and Create app stay the owner's.
- An uncertain answer stops the walk on its page (outlined, "answer
needed on ...") until the owner has set it; then it goes on.
Fixture apple-app-privacy-flow.html (first time, ?existing=1, decoys);
tests/console-flow.test.ts with the guardrail that no log line asks the
owner to click a navigation control.
- aso competitors: top apps per keyword from the iTunes Search API (name, developer,
rating count, release / update dates, localized genre), coverage gaps (words of 2+
developers), new entrants vs the last snapshot (.storebound/aso/competitors/)
- aso suggest: candidates from own text, competitor names, localized category names and
Apple Ads keyword suggestions (POST /v1/suggestions/keywords/query, relative 0-100
popularity, only with credentials); 100-byte keyword field per locale as a diff,
--write marks it a draft that check --aso and aso audit report
- aso audit: check --aso, free keyword room, rank trend arrows, gaps, Play short
description / density, App Store conversion, PPO / Play experiment ideas, next 3 actions
- MCP: read-only aso_competitors, aso_suggest, aso_audit; desktop ASO card (visx rank chart)
- docs: README, aso-basics, store-pitfalls (Search API order, no Play search API), CHANGELOG;
demo-app listing files; tests on recorded Search API and mocked Ads answers
Web capture runs frames in parallel browser contexts (default from the CPU count, lower for GPU-heavy capture),
logs n/total + ETA and goto / waitFor / eval / delay / screenshot per frame, writes .storebound/capture-report.json
with the slowest frames and steps. shots.capture.session 'per-language' boots the app once per language and device
and switches shots via pushState / popstate (navigate 'spa') or goto (navigate 'reload'), falling back to a fresh
page when a precondition fails. .storebound/capture-cache.json skips frames with unchanged inputs; --only-missing,
--force. shots render renders with --concurrency pages and async ffmpeg.
Lilita One lacks most of Latin Extended-A (Turkish s-cedilla, g-breve, dotted I ...), so Turkish titles were drawn
with a silent browser fallback while shots check passed. shots fonts now reads the cmap of every face (pure TS,
TTF/OTF/WOFF/WOFF2), adds a Noto fallback per missing character or fails with language + characters; render
measures which face drew each character (CDP probes) and records it in report.json; check errors on fallbacks the
config did not choose (shots.fonts.fallback) and on system-font glyphs. Default game title font: Paytone One.