From 0024ea49d32c8efaef2e342c966a49713c42a622 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 01:40:47 +0000 Subject: [PATCH] refactor(cli): share exec approvals save flow --- src/cli/exec-approvals-cli.ts | 133 +++++++++++++++------------------- 1 file changed, 58 insertions(+), 75 deletions(-) diff --git a/src/cli/exec-approvals-cli.ts b/src/cli/exec-approvals-cli.ts index 2b151d37f09..1f16531430e 100644 --- a/src/cli/exec-approvals-cli.ts +++ b/src/cli/exec-approvals-cli.ts @@ -89,6 +89,51 @@ async function loadSnapshotTarget(opts: ExecApprovalsCliOpts): Promise<{ return { snapshot, nodeId, source: nodeId ? "node" : "gateway" }; } +function exitWithError(message: string): never { + defaultRuntime.error(message); + defaultRuntime.exit(1); + throw new Error(message); +} + +async function loadWritableSnapshotTarget(opts: ExecApprovalsCliOpts): Promise<{ + snapshot: ExecApprovalsSnapshot; + nodeId: string | null; + source: "gateway" | "node" | "local"; + targetLabel: string; + baseHash: string; +}> { + const { snapshot, nodeId, source } = await loadSnapshotTarget(opts); + if (source === "local") { + defaultRuntime.log(theme.muted("Writing local approvals.")); + } + const targetLabel = source === "local" ? "local" : nodeId ? `node:${nodeId}` : "gateway"; + const baseHash = snapshot.hash; + if (!baseHash) { + exitWithError("Exec approvals hash missing; reload and retry."); + } + return { snapshot, nodeId, source, targetLabel, baseHash }; +} + +async function saveSnapshotTargeted(params: { + opts: ExecApprovalsCliOpts; + source: "gateway" | "node" | "local"; + nodeId: string | null; + file: ExecApprovalsFile; + baseHash: string; + targetLabel: string; +}): Promise { + const next = + params.source === "local" + ? saveSnapshotLocal(params.file) + : await saveSnapshot(params.opts, params.nodeId, params.file, params.baseHash); + if (params.opts.json) { + defaultRuntime.log(JSON.stringify(next)); + return; + } + defaultRuntime.log(theme.muted(`Target: ${params.targetLabel}`)); + renderApprovalsSnapshot(next, params.targetLabel); +} + function formatCliError(err: unknown): string { const msg = describeUnknownError(err); return msg.includes("\n") ? msg.split("\n")[0] : msg; @@ -268,45 +313,21 @@ export function registerExecApprovalsCli(program: Command) { .action(async (opts: ExecApprovalsCliOpts) => { try { if (!opts.file && !opts.stdin) { - defaultRuntime.error("Provide --file or --stdin."); - defaultRuntime.exit(1); - return; + exitWithError("Provide --file or --stdin."); } if (opts.file && opts.stdin) { - defaultRuntime.error("Use either --file or --stdin (not both)."); - defaultRuntime.exit(1); - return; - } - const { snapshot, nodeId, source } = await loadSnapshotTarget(opts); - if (source === "local") { - defaultRuntime.log(theme.muted("Writing local approvals.")); - } - const targetLabel = source === "local" ? "local" : nodeId ? `node:${nodeId}` : "gateway"; - if (!snapshot.hash) { - defaultRuntime.error("Exec approvals hash missing; reload and retry."); - defaultRuntime.exit(1); - return; + exitWithError("Use either --file or --stdin (not both)."); } + const { source, nodeId, targetLabel, baseHash } = await loadWritableSnapshotTarget(opts); const raw = opts.stdin ? await readStdin() : await fs.readFile(String(opts.file), "utf8"); let file: ExecApprovalsFile; try { file = JSON5.parse(raw); } catch (err) { - defaultRuntime.error(`Failed to parse approvals JSON: ${String(err)}`); - defaultRuntime.exit(1); - return; + exitWithError(`Failed to parse approvals JSON: ${String(err)}`); } file.version = 1; - const next = - source === "local" - ? saveSnapshotLocal(file) - : await saveSnapshot(opts, nodeId, file, snapshot.hash); - if (opts.json) { - defaultRuntime.log(JSON.stringify(next)); - return; - } - defaultRuntime.log(theme.muted(`Target: ${targetLabel}`)); - renderApprovalsSnapshot(next, targetLabel); + await saveSnapshotTargeted({ opts, source, nodeId, file, baseHash, targetLabel }); } catch (err) { defaultRuntime.error(formatCliError(err)); defaultRuntime.exit(1); @@ -345,20 +366,10 @@ export function registerExecApprovalsCli(program: Command) { try { const trimmed = pattern.trim(); if (!trimmed) { - defaultRuntime.error("Pattern required."); - defaultRuntime.exit(1); - return; - } - const { snapshot, nodeId, source } = await loadSnapshotTarget(opts); - if (source === "local") { - defaultRuntime.log(theme.muted("Writing local approvals.")); - } - const targetLabel = source === "local" ? "local" : nodeId ? `node:${nodeId}` : "gateway"; - if (!snapshot.hash) { - defaultRuntime.error("Exec approvals hash missing; reload and retry."); - defaultRuntime.exit(1); - return; + exitWithError("Pattern required."); } + const { snapshot, nodeId, source, targetLabel, baseHash } = + await loadWritableSnapshotTarget(opts); const file = snapshot.file ?? { version: 1 }; file.version = 1; const agentKey = resolveAgentKey(opts.agent); @@ -371,16 +382,7 @@ export function registerExecApprovalsCli(program: Command) { allowlistEntries.push({ pattern: trimmed, lastUsedAt: Date.now() }); agent.allowlist = allowlistEntries; file.agents = { ...file.agents, [agentKey]: agent }; - const next = - source === "local" - ? saveSnapshotLocal(file) - : await saveSnapshot(opts, nodeId, file, snapshot.hash); - if (opts.json) { - defaultRuntime.log(JSON.stringify(next)); - return; - } - defaultRuntime.log(theme.muted(`Target: ${targetLabel}`)); - renderApprovalsSnapshot(next, targetLabel); + await saveSnapshotTargeted({ opts, source, nodeId, file, baseHash, targetLabel }); } catch (err) { defaultRuntime.error(formatCliError(err)); defaultRuntime.exit(1); @@ -398,20 +400,10 @@ export function registerExecApprovalsCli(program: Command) { try { const trimmed = pattern.trim(); if (!trimmed) { - defaultRuntime.error("Pattern required."); - defaultRuntime.exit(1); - return; - } - const { snapshot, nodeId, source } = await loadSnapshotTarget(opts); - if (source === "local") { - defaultRuntime.log(theme.muted("Writing local approvals.")); - } - const targetLabel = source === "local" ? "local" : nodeId ? `node:${nodeId}` : "gateway"; - if (!snapshot.hash) { - defaultRuntime.error("Exec approvals hash missing; reload and retry."); - defaultRuntime.exit(1); - return; + exitWithError("Pattern required."); } + const { snapshot, nodeId, source, targetLabel, baseHash } = + await loadWritableSnapshotTarget(opts); const file = snapshot.file ?? { version: 1 }; file.version = 1; const agentKey = resolveAgentKey(opts.agent); @@ -436,16 +428,7 @@ export function registerExecApprovalsCli(program: Command) { } else { file.agents = { ...file.agents, [agentKey]: agent }; } - const next = - source === "local" - ? saveSnapshotLocal(file) - : await saveSnapshot(opts, nodeId, file, snapshot.hash); - if (opts.json) { - defaultRuntime.log(JSON.stringify(next)); - return; - } - defaultRuntime.log(theme.muted(`Target: ${targetLabel}`)); - renderApprovalsSnapshot(next, targetLabel); + await saveSnapshotTargeted({ opts, source, nodeId, file, baseHash, targetLabel }); } catch (err) { defaultRuntime.error(formatCliError(err)); defaultRuntime.exit(1);