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)

This commit is contained in:
CRTkafa 2026-10-21 12:40:26 +07:00
parent 164182012f
commit 00756e6908
19 changed files with 475 additions and 45 deletions

View file

@ -3,7 +3,7 @@
// storebound api list [--store apple|play] [--search text] [--json]
// storebound api coverage [--store apple|play] [--json]
// storebound api apple|play <operationId | METHOD path> [--param k=v ...] [--body file.json] [--upload file]
// [--out file] [--all-pages] [--json] [--dry] [--yes]
// [--out file] [--all-pages] [--json] [--dry] [--yes [--confirm <operationId>]]
// storebound api get apple|play <operationId> ... GET only (what the MCP tool api_get runs)
//
// GETs run right away. Writes print the exact request and are only sent with --yes in an interactive terminal;
@ -28,12 +28,13 @@ export const USAGE = `usage:
storebound api list [--store apple|play] [--search text] [--json]
storebound api coverage [--store apple|play] [--json]
storebound api apple|play <operationId | METHOD path> [--param k=v ...] [--body file.json] [--upload file]
[--out file] [--all-pages] [--json] [--dry] [--yes]
[--out file] [--all-pages] [--json] [--dry] [--yes [--confirm <operationId>]]
storebound api get apple|play <operationId> [--param k=v ...] [--all-pages] [--json] (GET only)
GETs run right away. Writes print the exact request and are sent only with --yes in a terminal; owner-only
operations (submit, release, delete, cancel, prices, testers, review replies, experiments) also ask you to type the
operation id. Full table: docs/api-coverage.md`;
operation id. Agents without a terminal: --yes --confirm <operationId> (must equal the operation id; plain writes
only, never owner-only operations). Full table: docs/api-coverage.md`;
export interface Row { store: Store; id: string; method: string; path: string; gate: GateKind; wrapped: string }
@ -144,6 +145,7 @@ export async function run(args: Args): Promise<void> {
kind, method: op.method, dry: args.has('dry'), yes: args.has('yes'), getOnly,
tty: stdinIsTTY() && !!process.stdout.isTTY,
agent: process.env.STOREBOUND_SERVE === '1' || process.env.STOREBOUND_MCP === '1',
confirm: args.get('confirm'), opId: op.id,
});
if (decision.action === 'refuse') {
const instead = op.method !== 'GET' ? dedicatedCommand(st, op.id) : null;