UNPKG

@phren/cli

Version:

Knowledge layer for AI agents - CLI, MCP server, and data layer

49 lines (48 loc) • 3.06 kB
import type { AgentHooks } from "./agent-hooks.js"; import { type Json, type Target } from "./protocol.js"; /** An agent's permission mode as its own footer names it, and the route that * changes it by pressing Shift+Tab through the harness's cycle. The phone's * mode picker reads `agentStatus.permissionMode` / `permissionModes` off the * chat status stream and posts one back here. Only Claude Code draws the mode * in its footer; Codex and OpenCode keep theirs in config, so they offer none. */ /** Claude Code's `permissionMode` values in Shift+Tab cycle order. "default" is * the footer's "manual mode on"; "auto" is "auto mode on". */ export declare const PERMISSION_CYCLE: readonly ["default", "acceptEdits", "plan", "auto"]; /** `bypassPermissions` is in the cycle only for a session launched allowing * bypass, so it is a valid mode but not part of the standard list. */ export declare const PERMISSION_MODE_VALUES: readonly ["default", "acceptEdits", "plan", "auto", "bypassPermissions"]; export type PermissionModeName = (typeof PERMISSION_MODE_VALUES)[number]; /** The modes a Claude pane offers, in Shift+Tab cycle order. `bypass` adds the * one only a session launched with --allow-dangerously-skip-permissions has. */ export declare function permissionModes(bypass: boolean): PermissionModeName[]; /** Claude's permission mode from the footer line its TUI draws under the * composer. The transcript lags it: a `permission-mode` row is written only * when a prompt is submitted, and a fresh session has no file yet. The line may * trail hints ("(shift+tab to cycle) · 1 agent"), so only its start counts. A * mode the footer does not mark is `undefined`: "manual mode on" is default. */ export declare function claudeFooterMode(screen: string): PermissionModeName | undefined; /** Only the owner changes a session's permission mode, from the phone. An * agent's call names its own pane (`origin`), and none is accepted: an agent * could otherwise lift itself or another pane past the per-grant * `maxPermissionMode` ceiling, up to bypassPermissions. Same rule as * `/v1/sudo/answer`. */ export declare function refuseAgentOrigin(actor: unknown): void; /** One Shift+Tab transaction per pane owns its terminal input until it ends, * like the settings switcher, so a mode change and a settings change never * press into the same composer at once. */ export declare class PermissionModeSwitcher { private readonly hooks; private readonly wait; private active; constructor(hooks: AgentHooks, wait?: number); private key; assertAvailable(target: Target): void; /** Steps the pane to `mode`, or refuses. Only Claude offers the cycle; the * machine's authority policy never caps an owner's own choice. */ set(target: Target, mode: PermissionModeName, actor?: unknown): Promise<Json>; private cycle; /** The mode after a press: polled from the screen until it differs from * `from`, because the TUI redraws the footer asynchronously. */ private changed; private assertLive; }