Bypass mode (owner opt-in, default off): storebound settings bypass on|off|status and a one-time question in init; MCP owner_step (owner-only commands, dry run first), owner-only api operations with --yes --confirm, console plans may press buttons.final; every action logged to .storebound/owner-actions.log; docs/bypass.md, agent rules, tests

This commit is contained in:
CRTkafa 2026-10-22 02:27:34 +08:00
parent 2598c4953a
commit 9bd17c401d
21 changed files with 218 additions and 13 deletions

View file

@ -10,6 +10,7 @@
// owner-only operations (submit, release, delete, cancel, prices, testers, review replies, experiments: cli/api/gate.ts)
// also need the operation id typed at the prompt. Under MCP or the desktop app no write is ever sent.
import { readFileSync, writeFileSync } from 'node:fs';
import { bypassOn } from './lib/bypass';
import { resolve } from 'node:path';
import type { Args } from './lib/args';
import { allOps, authFor, type BuiltRequest, buildRequest, resolveOp, send, sendAll } from './api/client';
@ -145,7 +146,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,
confirm: args.get('confirm'), opId: op.id, bypass: bypassOn(),
});
if (decision.action === 'refuse') {
const instead = op.method !== 'GET' ? dedicatedCommand(st, op.id) : null;