// Machine-readable fixes of scan and validate findings: the desktop's "Fix" button runs `action.method` with // `action.args` as a write (dry run, the native dialog showing it, then the real run with a host-minted token), so the // window never parses a finding's text. Only fixes an existing command fully determines get an action; the rest has // none. FIX_METHODS is the whole list: local config writes and store text pushes, never a submit, release or publish // (tests/fix-actions.test.ts). export interface FixAction { method: FixMethod; args: Record } export const FIX_METHODS = ['scan.write', 'play.listing', 'apple.listing', 'apple.review_details'] as const; export type FixMethod = typeof FIX_METHODS[number]; /** Scan rules `storebound scan --write` fixes: the detected Data safety / App Privacy answers go into the config. */ export const SCAN_WRITE_RULES = new Set(['privacy-labels']); /** The fix of one scan finding: `scan --write` while it would change the config (detected answers only). */ export function scanFixAction(rule: string, o: { configPath: string | null; declarationsChanged: boolean }): FixAction | undefined { return SCAN_WRITE_RULES.has(rule) && o.configPath && o.declarationsChanged ? { method: 'scan.write', args: {} } : undefined; } /** Validate findings fixed by pushing the listing files / config to the store (text only, never submitted). */ export const fixPlayListing = (): FixAction => ({ method: 'play.listing', args: {} }); export const fixAppleListing = (version: string): FixAction => ({ method: 'apple.listing', args: { version } }); export const fixReviewDetails = (): FixAction => ({ method: 'apple.review_details', args: {} }); /** Scan rules whose fix is a code or project-file change (Info.plist, AndroidManifest, Gradle, sources): the desktop * offers "Fix with AI" (the owner's local Claude Code, file tools only) or "Copy for AI" for them. Rules whose fix is a * compliance answer, a store form or listing text are not here. */ export const AI_FIX_RULES = new Set(['ats', 'att', 'purpose-strings', 'unused-permission', 'privacy-manifest', 'deprecated-api', 'private-api', 'ipv6', 'restore-purchases', 'account-deletion', 'subscription-info', 'login-services', 'review-prompt', 'placeholder-text', 'beta-wording', 'other-platforms', 'privacy-policy-link', 'kids-ads', 'play-fgs', 'play-target-sdk', 'play-ad-id', 'play-families-ad-id', 'play-exact-alarm', 'play-query-all-packages', 'play-full-screen-intent', 'play-all-files-access', 'play-photo-video', 'play-background-location', 'play-install-packages', 'play-sms-call-log', 'play-prominent-disclosure', 'play-16kb']);