desktop: a Fix button on scan and validate findings storebound can fix itself. Findings carry action { method, args } (cli/lib/fix-actions.ts); privacy-labels runs scan.write (scan --write-only, the dialog shows the config diff), Play listing gaps play.listing, a missing App Store localization or copyright apple.listing (editable version only), the App Review contact apple.review_details; each a dry run, the native dialog, then the confirmed run. --write-only is forbidden for MCP tools; tests pin the mapping, the round trip on a fixture and that no fix reaches a submit, release or publish
This commit is contained in:
parent
bd83d036ba
commit
992f5bcc0e
18 changed files with 257 additions and 37 deletions
|
|
@ -65,6 +65,11 @@ export const JSON_WRITES = new Set(['console_fill', 'owner_apple_submit', 'owner
|
|||
/** Write tools whose command may ask its own question (confirm()): a verified host token answers it, as for owner actions. */
|
||||
const TOKEN_ANSWERS = new Set(['console_fill']);
|
||||
|
||||
/** The one desktop exception to FORBIDDEN_ARGS: `scan --write-only` (scan.write, the Fix button of a privacy-labels
|
||||
* finding) writes the detected declarations into the config, only after the native dialog showed its diff and the
|
||||
* host minted a token. The MCP server (AI tools) never gets it (tests/fix-actions.test.ts). */
|
||||
export const DESKTOP_LOCAL_WRITES: Record<string, readonly string[]> = { scan_write: ['--write-only'] };
|
||||
|
||||
/**
|
||||
* Methods only the desktop profile has (not MCP tools): offline reads of the project's own files, local writes the
|
||||
* owner confirms in a native dialog, and `console.fill`. That one is a write: its dry run returns the answers it would
|
||||
|
|
@ -132,6 +137,8 @@ export const DESKTOP_ONLY: ToolDef[] = [
|
|||
props: { from: { type: 'string', pattern: ART_FROM_RE.source, description: 'The picked file (absolute path)' },
|
||||
to: { type: 'string', pattern: ART_TO_RE.source, description: 'The image to replace, relative to the app folder' } },
|
||||
required: ['from', 'to'], args: i => ['--from', String(i.from), '--to', String(i.to)] },
|
||||
{ name: 'scan_write', title: 'Write the detected declarations', command: ['scan', DESKTOP_LOCAL_WRITES.scan_write![0]!], write: true, network: false, idempotent: true,
|
||||
description: 'The Fix of a scan finding (privacy-labels): writes the Data safety / App Privacy answers the scan detected from the SDKs into the config (dataSafety / appPrivacy blocks; the rest of the file kept). The dry run shows the config diff; "ask the owner" answers stay questions. Nothing goes to a store and nothing is committed.' },
|
||||
{ name: 'prices_current', title: 'Current prices', command: ['prices', 'export'], write: false, network: true,
|
||||
description: 'Read-only: the current price of every product on both stores per region (Apple manual prices, with with_automatic also the equalized ones). Writes nothing.',
|
||||
props: { store: { type: 'string', enum: ['apple', 'play'] }, with_automatic: { type: 'boolean', default: false } },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue