Skip to content

Releases

v0.23.0 — Multi-Agent Compatibility (Antigravity & Codex Support)

Choose a tag to compare

@tjdrhs90 tjdrhs90 released this 27 Oct 03:34

Added

  • Multi-Agent Adapter Support: Added phase dispatch mapping in the main orchestrator skill for seamless execution in Google Antigravity, OpenAI Codex, and generic agents.
  • Agent Compatibility Guide: Added docs/agent-compatibility.md detailing setup and execution across different coding assistants.
  • Documentation: Updated README and README.ko with Antigravity / multi-agent skill setup instructions.
  • Bumped version to 0.23.0 in .claude-plugin/plugin.json.

v0.22.0 — UMP 동의 폼 뒤에 ATT

Choose a tag to compare

@tjdrhs90 tjdrhs90 released this 01 Sep 08:39

Fixed

  • UMP 동의 폼과 ATT 요청 순서를 바로잡았다. 종전 안내는 await requestATT() 를 먼저,
    await loadConsentForm() 을 나중에 부르게 되어 있었다. AdMob 콘솔에서 만드는 ATT 안내
    메시지는 "다음 화면에서 '허용'을 탭하세요" 라고 말하므로, ATT 가 먼저 뜨면 그 안내가 뒤에
    나와 앞뒤가 맞지 않는다. 추적 허용률은 곧 IDFA 확보율이고 eCPM 이라 그냥 어색한 정도로
    끝나지 않는다. 시작 순서를 loadConsentForm() → requestATT() → MobileAds.initialize()
    로 바꿨다.
  • 동의 완료 콜백이 두 경로에서 불린다는 점을 문서에 남겼다. 폼 종료와 정보 갱신 실패가
    같은 완료 지점으로 들어온다. 가드가 없으면 폼이 떠 있는 동안 ATT 가 그 위에 겹쳐 뜬다 —
    실제로 출시된 앱에서 그렇게 나갔다 (2026-08, 51개 앱 점검에서 발견).

Added

  • Evaluator R6 게이트에 순서 검사를 넣었다. lib/main.dart 에서 requestATT() 가
    loadConsentForm() 보다 먼저 나오면 FAIL 로 잡는다.

v0.21.0 — store-review findings from a 50-app maintenance round

Choose a tag to compare

@tjdrhs90 tjdrhs90 released this 25 Aug 10:13

Added

  • App Store Connect submission over the API is documented, and the old claim that it cannot be
    automated is corrected.
    POST /v1/appStoreVersionSubmissions has been deprecated —
    it answers 403 "Allowed operation is: DELETE" — and the working flow is three calls:
    reviewSubmissions → reviewSubmissionItems → PATCH { submitted: true }. The submit skill now
    carries that flow as a reference section. The pipeline still pauses before the final submission,
    but now says so as a deliberate checkpoint rather than an API limitation.
  • Resubmitting after a rejection. A rejected version stays attached to the submission that
    rejected it, so adding it to a new one fails with STATE_ERROR.ITEM_PART_OF_ANOTHER_SUBMISSION;
    every item under a submission in state UNRESOLVED_ISSUES has to be detached with
    { removed: true } first. And a rejection is edited in place — REJECTED,
    DEVELOPER_REJECTED, METADATA_REJECTED, INVALID_BINARY are all editable states, so a new
    version record is both unnecessary and rejected as a duplicate version string.
  • Age rating: the declarations Apple added in 2026. userGeneratedContent, messagingAndChat,
    ageAssurance, gunsOrOtherWeapons, advertising, healthOrWellnessTopics, parentalControls.
    An app record that only answered the old questionnaire cannot enter review. Any AdMob build must
    answer advertising = Yes — banners count — or Apple's automated analysis bounces it before a
    human looks. ageRatingDeclarations is write-only over the API (GET → 403), so this is not
    auditable programmatically; the checklist says to open the Connect UI.
  • Play Console declarations come from the merged manifest. A dependency's own
    AndroidManifest.xml is merged into the bundle, so a permission nobody typed becomes a
    declaration to file under App content → Needs attention. FOREGROUND_SERVICE_* requires a form
    with a mandatory demo video showing the feature working while the app is backgrounded, and past
    the compliance deadline it blocks updates while the live listing stays up. Deleting your own
    <uses-permission> line does nothing when the dependency declares it.
  • Metadata locks at release, not at submission — whatsNew, store URLs, and review notes stay
    editable through WAITING_FOR_REVIEW and IN_REVIEW, and start returning 409 at
    READY_FOR_SALE.
  • Resolution Center has no API. The rejection text cannot be read and cannot be replied to;
    appStoreReviewDetail.notes is the only reviewer-facing field that can be written, so a fix
    explanation belongs there before the resubmission rather than after it.
  • TARGETED_DEVICE_FAMILY has to match reality — declaring iPad ("1,2", a template default)
    obliges the game to support every iPad orientation, and a portrait-only phone game shipped that
    way is rejected under 4.0.
  • A released version string cannot take another build ("Invalid Pre-Release Train … closed for
    new build submissions"
    ); bump the name in pubspec.yaml and leave +N, the Android
    versionCode, on its own schedule.
  • Build-machine gotchas: a build script that git checkouts a generated-but-tracked file
    (project.pbxproj) silently reverts deliberate source edits, so the repo and the shipped binary
    disagree with no error anywhere — copy and mv back instead; editing a shell script while it runs
    corrupts the running shell's byte offsets; simultaneous iOS + Android release builds OOM a 16 GB
    machine; and a portfolio sweep should take its app list from GET /v1/apps, not from directory
    layout, which misses every project that builds iOS from its own tree.

v0.20.0 — fix three wrong commands in screenshot/ASO guidance

Choose a tag to compare

@tjdrhs90 tjdrhs90 released this 04 Aug 02:22

Fixed

  • Screenshot capture wrote nothing at all: the screenshot skill's test-driver boilerplate was
    Future<void> main() => integrationDriver();, but integrationDriver has no default screenshot
    writer
    — its native path is guarded by onScreenshot != null, so every takeScreenshot byte was
    silently discarded and no PNG was ever produced. The skill now supplies an onScreenshot callback
    that writes to $SCREENSHOT_DIR (default build/screenshots), the Phase 2 locale loop gives each
    locale its own staging directory, and Phase 4 copies from there into the fastlane paths with a
    per-locale file count printed. The old claim that flutter drive "writes PNG files to <game>/"
    was wrong and is gone. Verified: the callback type-checks against the real ScreenshotCallback
    typedef (dart analyze, no issues).
  • sips -s format png was recommended to strip alpha, and it does not: it re-encodes and keeps
    the channel, so the "flatten before upload" step left the App Store alpha rejection in place — the
    exact rejection the guidance exists to prevent. (The evaluator's sips -g hasAlpha detector was
    correct all along; only the fix was wrong.) Replaced with two verified recipes —
    magick … -alpha remove -alpha off, or a JPEG round-trip using macOS built-ins — both confirmed to
    turn hasAlpha: yes into hasAlpha: no on a real RGBA PNG.
  • ASO keyword length was measured in bytes, wasting two thirds of the field: the skill told you to
    check keywords.txt with echo -n … | wc -c, which counts bytes; one Hangul syllable is 3
    bytes in UTF-8, so a valid 97-character Korean string measures 247 and looks 2.5× over the 100-char
    cap. Following it truncates Korean keywords to ~33 characters. Now counts characters (and notes
    that a here-string <<< adds a newline and inflates the count by 1). Both worked examples were
    also mislabelled — "exactly 97 chars" was 53 and "exactly 96 chars" was 87, i.e. both violated the
    skill's own 95–100 rule; replaced with strings measured at 97 (KO) and 99 (EN).
  • validate.sh now guards all three against regression, and game-gotchas.md records them. Each
    guard was confirmed to actually fail when the corresponding guidance is removed.

Full history: CHANGELOG.md