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

20
cli/settings.ts Normal file
View file

@ -0,0 +1,20 @@
// Per-machine storebound settings (never in a project's config or repo).
// storebound settings bypass on | off | status owner opt-in: the agent also presses the owner-only buttons
// (docs/bypass.md); default off
import type { Args } from './lib/args';
import { BYPASS_NOTICE, bypassOn, OWNER_COMMANDS, readSettings, setBypass, settingsFile } from './lib/bypass';
import { log, printJson } from './lib/log';
export async function run(args: Args): Promise<void> {
const [what, value] = args._;
if (what !== 'bypass') throw new Error('usage: storebound settings bypass on | off | status');
if (value === 'on' || value === 'off') {
setBypass(value === 'on');
log('settings', value === 'on'
? `${BYPASS_NOTICE}. Unlocked: ${OWNER_COMMANDS.join(', ')}, owner-only API operations (storebound api ... --yes --confirm <operationId>) and console final buttons.`
: 'bypass mode is OFF: owner-only steps are the owner\'s again (MCP hides owner_step, api refuses owner operations, console plans stop at buttons.final)');
} else if (value && value !== 'status') throw new Error('usage: storebound settings bypass on | off | status');
const s = readSettings();
if (args.has('json')) { printJson({ bypass: bypassOn(), since: s.bypass?.since ?? null, file: settingsFile() }); return; }
if (!value || value === 'status') log('settings', `bypass mode: ${bypassOn() ? 'ON' : 'off'}${s.bypass?.since ? ` (since ${s.bypass.since})` : ''} · ${settingsFile()}`);
}