Commit graph

17 commits

Author SHA1 Message Date
CRT
b5b8f2da9d play data-safety: PSL_SUPPORT_DATA_DELETION_BY_USER as Play's single choice (partialDeletion true | false | 'auto90'), drop the removed PSL_DATA_COLLECTION_USER_REQUEST_DELETE (deletionRequest deprecated, check notes it); ship Google's empty form (cli/data/play-data-safety-form.csv, exported 2026-10-12), take every Answer requirement from it and report pairs not in it (formPairIssues) in check, declarations and play data-safety. Pitfall 21 2026-10-12 09:34:12 +08:00
CRT
c9a7f095c4 console: agent-first mode (console plan / console verify), verified App Privacy and Play Create app facts
- `storebound console plan <form> [--json] [--lookup]`: read-only plan for an AI agent that drives the browser
  itself: start URL (deep links), ordered steps, answer sheet with the console's exact labels (certain / ask owner,
  curly quotes noted), never-press list, verified UI facts, driving guidance (in-page async loop + window.__log),
  verify instructions. All six forms.
- `storebound console verify <form> [--from-text <file|->]`: App Privacy per-type summaries from page text, Play
  Create app from input states, content rating / target audience summaries, App Store record and age rating from
  the API; exit 1 on a mismatch.
- MCP: console_plan, console_verify (read-only); console fill stays off MCP.
- App Privacy (verified 2026-10-12): two information steps, unlabeled purpose checkboxes (nearest parent text),
  "Definitions and Examples" never pressed; fixture and engine follow.
- Play Create app (verified 2026-10-12): /developers/<id>/create-new-app, App package name + read-only Check
  availability, material-radio inner [role=radio] click, app dashboard URL and play.appId, service account
  "Add app" as an owner step.
- console-autofill skill rewritten agent-first; agents-core rule 10; README; pitfalls 12, 18 (confirmed sign-out),
  19; CHANGELOG; play-first-release.
2026-10-12 08:39:12 +08:00
CRT
0035931734 console fill: never copy Google session cookies by default (device-bound); own profile in a Chrome started without automation switches
Google binds its session cookies to the device (Device Bound Session Credentials) and signs out
sessions whose cookies look stolen, which can sign the owner out of their real Chrome. The default is
now storebound's own profile per store; storebound starts Chrome itself (--user-data-dir,
--remote-debugging-port=0, no --enable-automation, navigator.webdriver false) and attaches over CDP.
--use-chrome-session google|apple is an explicit opt-in that warns. /signin/rejected is said plainly.
2026-10-12 07:46:38 +08:00
CRT
3aedf9e137 console fill: sign-in only by the top-level URL, the main frame's form or an Apple sign-in frame
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.
2026-10-12 07:29:11 +08:00
CRT
b48407115e console fill: checkbox / radio ticks are gated on agreements only (help text like 'saved place in a game' no longer blocks Product Interaction); buttons keep the full word gate 2026-10-12 07:19:50 +08:00
CRT
8b669f5c86 console fill play-app-record: read the real account chooser, match names loosely
With the copied Chrome profile, `console fill play-app-record` stopped with
"no developer account named "<name>" (play.developerAccount) on the
chooser" although the name was there: the real "Choose developer account"
rows are not plain /developers/<id> text links (nested spans, icon-font
glyphs, role=button rows with the id in a data attribute, an avatar row
whose id only its click reveals).

- readChooser: every visible clickable row in the page content (header
  and navigation left out); the name is the first visible line (icon
  fonts, images and aria-hidden parts skipped); the id comes from
  /developers/<id> in any attribute, else a data-*id attribute, else ''
  (the row is then opened through the account-switch gate and the id is
  read from the URL). "Create a new developer account" is not an account.
- matchAccount: exact spelling, then spaces and case aside (Turkish I/ı
  folded), then a unique prefix. A case pair (ACME / Acme) needs the
  exact spelling; otherwise it stops and lists both with their ids.
- One developer account: picked (a different play.developerAccount is
  said). Not found: every visible account is listed with its id.
- The resolved developerId is remembered as before.

Fixtures play-chooser-real.html (the owner's chooser shape, placeholder
names) and play-chooser-one.html; tests for exact, case pair, prefix,
single account and not found.
2026-10-12 07:12:05 +08:00
CRT
8ffc83bb39 console fill: walk the whole form; the owner only reviews and presses the final button
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.
2026-10-12 06:51:01 +08:00
CRT
b39e44e6ab console fill: one app shown twice is one app; App Privacy opens by app id via the API
`console fill apple-app-privacy` without apple.appId stopped at "the app
in the list" with "more than one app matches: X | X" for an account with
one app: the Apps grid names each app twice (the icon link's aria-label
and the title link), both opening the same /apps/<id>/... page.

- pickApp tells hits apart by the app they open (/apps/<id>, else the
  link target), not by name. Two apps of one name with different targets
  still stop and are listed.
- Without apple.appId, but with App Store Connect API credentials, the
  app id is looked up from apple.bundleId (GET /v1/apps?filter[bundleId],
  as `apple status` does), cached in .storebound/console-app-ids.json, and
  App Privacy opens by deep link. Without credentials, or when the lookup
  fails, the Apps list by name is used, and the log says so.

Fixture asc-apps-card.html (a card with the name in the title and an
aria-label); tests for both paths.
2026-10-12 06:32:21 +08:00
CRT
de243cdbd9 tests: profile persistence runs in a real Chrome, in its own shard
The two "session cookie survives closing and relaunching storebound's own
profile" tests failed with Playwright's headless shell, which ignores
--restore-last-session. They now live in tests/console-persist.test.ts
and launch the same browser kind console fill uses for its profile (the
resolver's "visible" kind: Google Chrome, else the full Chromium; headless
here, so no window). They skip with the reason only when neither is
installed. All other browser tests keep the fast headless shell. The file
is HEAVY in tools/ci-plan.ts, so it never shares a shard with another
browser suite.
2026-10-12 06:27:42 +08:00
CRT
04fb0089b5 Merge remote-tracking branch 'origin/main' into play-app-record
# Conflicts:
#	CHANGELOG.md
#	docs/pitfalls.md
#	skills/store-pitfalls/SKILL.md
#	tests/console-fill.test.ts
2026-10-12 05:24:52 +08:00
CRT
a5295db539 browser tests: deterministic under load
The afterAll hook of tests/console-fill.test.ts timed out (30 s) in 2 of 3
runs with 10 CPU hogs. Cause: Google Chrome (the fallback when playwright's
Chromium is not downloaded) hangs in its own shutdown after loading http
pages until its 10 s teardown watchdog fires; under load that passed 30 s.

- tests/helpers/browser.ts: one shared launch per file as a browser server
  with a 60 s launch timeout, killed at the end (throwaway profile, nothing
  to flush); a launch timeout fails instead of silently skipping; contexts
  and engine runs tracked per test and closed in afterEach (capped);
  event-driven waits for engine log lines
- console-fill: explicit test timeouts, slow tests marked, waits expected
  to succeed get a long cap (they return at once), sign-in / watching
  navTimeoutMs 1.5 s -> 5 s, persistent-profile Chromium closed in finally,
  temp account dirs removed
- site-overflow, console-session: same plumbing (site-overflow's afterAll
  had bun's 5 s default)
- console session: launchTimeoutMs option (tests only)
2026-10-12 04:54:07 +08:00
CRT
75d6f4cb71 console fill play-app-record: Play Console's Create app form (account picked by developerId / workspace / play.developerAccount, else stop and list; Create app opener allowlisted only on the app list, never in the form, EN + TR; name, default language, app or game, free or paid as an owner check; declarations never ticked; package name set by the first AAB upload) 2026-10-12 03:48:20 +08:00
CRT
8186b25575 console fill: User Access radios found under a plain heading (real App Store Connect), a lasting partial miss fills every field found and leaves only the missing ones to the owner 2026-10-12 03:05:11 +08:00
CRT
21c0c2ed60 console fill: sign-in detected by URL, frame and text; keeps watching after the fallback; session kept across relaunches; one login across Play developer accounts and App Store Connect teams 2026-10-12 02:54:48 +08:00
CRT
ce69fbd600 console fill: opens the form itself and reuses the owner's Chrome sign-in
Navigation after sign-in (navPlan + navigate): App Store Connect Apps > + > New App
(EN/TR), App Privacy by /apps/<appId>/distribution/privacy or the app list, Play app
list by package name > Policy and programs > App content > Start / Manage. Every
navigation click goes through navClick: the click gate stays absolute, only a link
named exactly Start / Manage / Başla / Yönet passes. Each step is logged; a step not
found in time or two matching apps -> the printed steps and wait (no crash).
The TR gate now refuses "uygula" (apply) but not "uygulama" (app).

Browser (cli/console/session.ts): attach to a Chrome with remote debugging (--cdp or
DevToolsActivePort), else on macOS a temporary profile with only Local State and the
profile's Cookies filtered to the console hosts, opened in real Chrome and deleted at
the end, else storebound's own profile (--fresh-profile). Cookies are never printed.
Desktop: fresh_profile option, the dialog says it uses the Chrome sign-in.
Tests: navigation fixtures (ASC EN/TR, Play list, App content, missing step,
duplicates, deny-listed decoys), session file selection, host filter, cleanup, and a
real-Chrome copy-mode test on a throwaway profile and a local site.
2026-10-12 02:21:35 +08:00
CRT
4a894a1937 growth extras: MCP safe tools, README and CHANGELOG, socialMedia age rating defaults, regenerated adapters and API coverage 2026-10-12 00:19:32 +08:00
CRT
cea2dffdc3 growth extras: prices ppp, ads apple, web, apple adhoc, play share, revenuecat, console fill (+ desktop button) 2026-10-12 00:14:00 +08:00