021c0eef5a
Regenerate the API tables with forward slashes
2026-10-23 13:13:45 +08:00
54451c87c8
Regenerate the API tables (wrapped.gen.ts, api-coverage.md); 0.8.41 notes move to Unreleased
2026-10-23 12:29:24 +08:00
00756e6908
Screenshot guardrails: name every screenshot not COMPLETE on 409 ASSET_IN_POST_PROCESSING (submit, validate; stuck after 5 min in UPLOAD_COMPLETE), apple screenshots --repair-stuck replaces only those in place, part uploads without Expect: 100-continue (failed part deletes the reservation, one retry, never committed), storebound api --confirm <operationId> for agents' plain writes (never owner-only)
2026-10-21 18:08:57 +07:00
d427b5c4a4
apple game-center: literal API paths (query guard reads them); api coverage regenerated
2026-10-21 05:29:08 +07:00
74101edeca
api tables regenerated (the new creative-assets and platform commands wrap more operations)
2026-10-20 03:08:37 +07:00
183579449c
apple creative-assets: select Header and Search Results assets once processed (Prepare for Submission), not once approved: Apple reviews an asset only in a review submission, so 0.8.13 waited forever; upload and select in one run with a bounded processing wait; --add-for-review puts unreviewed assets into the draft review submission (never submits); --verify reads every slot back read-only (MCP apple_creative_assets_verify); a rejected file or one that failed processing twice is not re-uploaded, an archived copy is unarchived; fake commits library assets to PREPARE_FOR_SUBMISSION; pitfall 76 rewritten; apple-name check test only looks at name hints
2026-10-19 05:42:53 +07:00
e5369090fa
apple creative-assets: App Store Header and Search Results (PRODUCT_PAGE_HEADER_ASSET, APP_STORE_SEARCH_RESULTS_ASSET) through the App Asset Library: local size / alpha / video checks, upload once by MD5, select only approved assets, replace on a changed file; check / validate note, MCP tool, gallery and desktop Art row, docs, pitfall 75
2026-10-18 13:10:20 +07:00
b830a99a5f
First in-app purchases left out of a review are caught (pitfall 70): firstProductGaps in validate / release plan (blocker) and the apple submit plan (refuses to leave a never-approved first product out); apple status (WARN + firstProductGaps in --json), release status and the desktop checks warn while a version waits for or is in review without it; iap-review says 'ready, not submitted yet' instead of 'complete'
2026-10-15 19:31:26 +08:00
357319a775
--json prints only JSON on stdout (withJsonOutput around every command: logs, tables and prompts to stderr; printJson everywhere; test runs every --json command against the fake stores and parses stdout); prices ppp compares like with like: par = the store's own US-equivalent price (Play convertRegionPrices, Apple equalizations; offline base x fx x (1 + VAT) rounded up) scaled by the PPP price level; defaults only lower, only price levels <= 0.5, World Bank high-income at par, CN at par on Apple and skipped on Play, never above par (--only-decreases, --max-ratio, --min-ratio, --max-level, --include-high-income; --floor / --ceiling kept), top-10 revenue market drops > 20 % warned (sales reports, else a static list), unchanged regions out of the sheet; price changes of existing products only with --allow-price-changes, TTY or not (a terminal yes covered them), then their own question listing each old -> new, held section in dry runs (play products, prices import, play / apple subscriptions); pitfalls 61-63; tests
2026-10-14 17:36:00 +08:00
7219ded3e8
template compliance answers never reach a store: init writes unanswered (dataSafety, appPrivacy, reviewNotes, ageRating, accounts, reviewAccess), older configs are recognised by the template values; check / validate / scan block, play data-safety (also --dry), console plan / fill, apple review-details and appinfo refuse. onboard --declarations replaces them on a live app: name and copyright from the stores (a copyright with a private term is left out), the rows the code proves (scan proposal, sign-up methods from auth code and login SDKs), the rest as one owner question list. play data-safety --dry prints the answers that change (old -> new, account and deletion first) against the last uploaded CSV; pitfall 60; tests
2026-10-14 11:36:30 +08:00
00be838b76
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
7ac028421a
store-only apps edit their listing on the store (storebound listing live / set: old -> new per field with the checks, a PATCH of only the edited fields; serve listing.set is the one store-only write, its token bound to the store ids; policy.rs STORE_ONLY_WRITES, write_with_confirm for store targets); screenshot captions per language and scene edited as a text edit of the shots copy JSON (JSON files keep their layout); Play content rating, target audience and App content answers in App info; docs/console-parity.md after the editors (73 rows: 55 complete, 18 with the reason) and tests/console-parity.test.ts keeping it honest
2026-10-14 00:54:56 +08:00
7b05e4b396
auto-read after the rebase: results through usable / failureText, issuesError notice kept, scheduler 'accounts' (no credentials word in the webview), fixtures and generated tables for health_issue
2026-10-13 23:41:36 +08:00
e5f148e534
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
bba46b5c7f
apple testflight distribute: a build's groups read per group (GET /v1/betaGroups/{id}/relationships/builds) instead of GET /v1/betaGroups?filter[builds]=, which App Store Connect refuses with 400 although the spec declares it; internal all-builds groups reported as already available and never sent the build; a re-run adds nothing; configured groups missing on App Store Connect point at groups sync, unknown ones list what exists; APPLE_LIVE_REJECTED (refused by storebound api too), tests/asc-query-guard.test.ts checks every App Store Connect GET with a query in cli/ against the spec's declared parameters, and the fake App Store Connect answers 400 to undeclared or live-refused parameters (pitfall 42)
2026-10-13 06:03:16 +08:00
1724296e59
apple resubmit: REJECTED review submission items are marked resolved before the submit (PATCH reviewSubmissionItems resolved: true; the version item by default, IAP / subscription items with --resolve-iaps), plan table 'mark resolved' rows; on 409 'not ready yet' the items are re-read and a REJECTED item out of scope stops the run at once naming it and how to resolve it, backoff only when none is left; an empty READY_FOR_REVIEW draft is never canceled (409 'not in cancellable state'): left as is, no cancel command, apple status labels it harmless and treats the cancel 409 as such; fake ASC blocks submit on REJECTED items and refuses to cancel empty drafts. Pitfall 30
2026-10-12 10:45:05 +08:00
0da5ee9d01
apple resubmit after a rejection: iap-submit reuses the open review submission (UNRESOLVED_ISSUES gets only missing items and is resubmitted, a draft is reused, one waiting for or in review means nothing is sent), never a second draft; 409 ITEM_PART_OF_ANOTHER_SUBMISSION names the other submission instead of the list-lag message, a draft the run created is canceled and the named one used; submit retried with backoff and heartbeat while Apple says not ready yet; new apple resubmit --build <n> (build by number, plan table, --yes); apple status lists UNRESOLVED_ISSUES items and the resubmit command. Pitfall 30
2026-10-12 10:34:12 +08:00
b7bfe89151
Play console steps without an API as agent plans: play-store-settings (App category; play listing cannot set it), play-app-content (every card in order, one owner batch) and its cards (privacy policy, ads, sign in details, advertising ID, government, financial, health), play-production-countries and play-production-release; IARC plan with the Terms of Use agreement, follow-ups (console.contentRating.details, products[].randomRewards, social) and the Summary's final Save; config play.category / countries / managedPublishing, console.appContent; check, validate, play status and play release reminders; inPageLoop helper and material checkbox clicks; App Privacy published signal; first IAPs via apple iap-submit --with-version. Pitfalls 27, 28
2026-10-12 10:16:34 +08:00
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
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
a2009fa7ac
idempotency: apple listing findOrCreate / createOnce, play listing re-plan in the edit, data-safety hash, twice-run tests for the last open rows
2026-10-12 04:24:45 +08:00
8f41ed4c02
Merge origin/main into idempotency
2026-10-12 04:01:25 +08:00
00cf2ed341
idempotency: WIP
2026-10-12 04:00:58 +08:00
dc3ff364a4
api: refresh coverage tables (iap-review reads more operations)
2026-10-12 03:30:15 +08:00
6f561393f4
api tables regenerated after the merge
2026-10-12 03:30:08 +08:00
b88648499e
apple listing, play listing, apple appinfo: the dry run prints a real plan (version decision, old -> new per field, draft locales skipped); the real run asks and applies exactly it
2026-10-12 03:29:38 +08:00
20f8d6a311
Merge origin/main into close-gaps
2026-10-12 01:26:37 +08:00
8a23bf7eec
live read run fixes: Xcode-managed profiles in signing, TestFlight-only release trains, scan skips agent worktrees and takes an absolute --config, --all-pages paging meta, iap-submit json, report hints
2026-10-12 01:24:56 +08:00
236977940e
flows, listing translate, scan 2.2 + --originality, prices export with subscriptions, site sections
...
- storebound flow list|validate|run: repo-local workflows (store/workflows/*.yml, storebound.workflows.*), writes dry unless --apply, owner steps never run, --from / --resume; init templates for app and game; MCP flow_list + dry flow_run; release-flows skill
- storebound listing translate|check|reviewed: per-language listing drafts with store limits and keyword rules, agent or --translate hook, marked until reviewed; MCP listing_translate / listing_check; listing-localization skill
- scan: Apple 2.2 beta/demo/test wording rule; scan --originality [--against]
- prices export includes subscriptions; prices import skips their rows
- site: rejection scan section, Desktop app section with fixture-mode screenshots, Everything else grid, FAQ 4.3 answer
- README, CHANGELOG, adapters, API tables
2026-10-12 01:24:21 +08:00
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
d972c36fa8
Merge store-ops: TestFlight wait / expire, IAP review submissions, pulls, offers, CPP, events, reports, triage, ASO rank, ads scan
...
Conflicts resolved for both sides:
- cli/lib/plist.ts, cli/lib/zip.ts: one implementation each. plist reads XML (text or
bytes, attributes tolerated) and binary plists; ads scan now reads bytes, so a binary
Info.plist works too. zip gains unzip() for the Play report exports on top of
zipEntries / zipRead.
- apple upload waits with testflight wait's loop (waitForBuild) instead of its own copy;
BUILD_DONE removed.
- config, credentials (profiles, keystore, ASC_VENDOR_NUMBER, now also a profile key),
command table, MCP tools, credentials template, README, CHANGELOG: union.
- MCP: --write stays forbidden; the three pull tools are the listed local-file exception
(LOCAL_WRITE_TOOLS), so scan --write remains unreachable.
- Adapters and API coverage tables regenerated.
2026-10-12 00:07:26 +08:00
2a91a791be
api: refresh the coverage tables after the build and signing commands
2026-10-11 23:48:30 +08:00
77aa09235e
storebound api: every App Store Connect and Google Play operation
...
- 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
2026-10-11 23:37:09 +08:00