Skip to content

Commit bdbcef4

Browse files
committed
feat: Add "bypass permissions" mode
1 parent 8211a91 commit bdbcef4

File tree

8 files changed

+41
-15
lines changed

8 files changed

+41
-15
lines changed

apps/twig/src/main/services/agent/schemas.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ export const credentialsSchema = z.object({
1010
export type Credentials = z.infer<typeof credentialsSchema>;
1111

1212
// Execution mode schema
13-
export const executionModeSchema = z.enum(["plan", "acceptEdits", "default"]);
13+
export const executionModeSchema = z.enum([
14+
"plan",
15+
"acceptEdits",
16+
"default",
17+
"bypassPermissions",
18+
]);
1419
export type ExecutionMode = z.infer<typeof executionModeSchema>;
1520

1621
// Session config schema
@@ -41,7 +46,9 @@ export const startSessionInput = z.object({
4146
permissionMode: z.string().optional(),
4247
autoProgress: z.boolean().optional(),
4348
model: z.string().optional(),
44-
executionMode: z.enum(["plan", "acceptEdits", "default"]).optional(),
49+
executionMode: z
50+
.enum(["plan", "acceptEdits", "default", "bypassPermissions"])
51+
.optional(),
4552
runMode: z.enum(["local", "cloud"]).optional(),
4653
/** Additional directories Claude can access beyond cwd (for worktree support) */
4754
additionalDirectories: z.array(z.string()).optional(),
@@ -142,7 +149,7 @@ export const setModelInput = z.object({
142149
// Set mode input
143150
export const setModeInput = z.object({
144151
sessionId: z.string(),
145-
modeId: z.enum(["plan", "default", "acceptEdits"]),
152+
modeId: z.enum(["plan", "default", "acceptEdits", "bypassPermissions"]),
146153
});
147154

148155
// Subscribe to session events input

apps/twig/src/main/services/agent/service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ interface SessionConfig {
166166
logUrl?: string;
167167
sdkSessionId?: string;
168168
model?: string;
169-
executionMode?: "plan" | "acceptEdits" | "default";
169+
executionMode?: "plan" | "acceptEdits" | "default" | "bypassPermissions";
170170
/** Additional directories Claude can access beyond cwd (for worktree support) */
171171
additionalDirectories?: string[];
172172
}

apps/twig/src/renderer/features/message-editor/components/ModeIndicatorInput.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { ExecutionMode } from "@features/sessions/stores/sessionStore";
22
import { useCwd } from "@features/sidebar/hooks/useCwd";
3-
import { Circle, Pause, Pencil, ShieldCheck } from "@phosphor-icons/react";
3+
import { LockOpen, Circle,Pause, Pencil, ShieldCheck } from "@phosphor-icons/react";
44
import { Flex, Text } from "@radix-ui/themes";
55
import { trpcVanilla } from "@renderer/trpc";
66
import { useQuery } from "@tanstack/react-query";
@@ -33,6 +33,11 @@ const modeConfig: Record<
3333
icon: <ShieldCheck size={12} weight="fill" />,
3434
colorVar: "var(--green-11)",
3535
},
36+
bypassPermissions: {
37+
label: "bypass permissions",
38+
icon: <LockOpen size={12} weight="bold" />,
39+
colorVar: "var(--red-11)",
40+
},
3641
};
3742

3843
export function ModeIndicatorInput({ mode, taskId }: ModeIndicatorInputProps) {

apps/twig/src/renderer/features/sessions/components/SessionView.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ import { InlinePermissionSelector } from "./InlinePermissionSelector";
2929
import { PlanStatusBar } from "./PlanStatusBar";
3030
import { RawLogsView } from "./raw-logs/RawLogsView";
3131

32-
const EXECUTION_MODES: ExecutionMode[] = ["plan", "default", "acceptEdits"];
32+
const EXECUTION_MODES: ExecutionMode[] = [
33+
"plan",
34+
"default",
35+
"acceptEdits",
36+
"bypassPermissions",
37+
];
3338

3439
function cycleMode(current: ExecutionMode): ExecutionMode {
3540
const currentIndex = EXECUTION_MODES.indexOf(current);

apps/twig/src/renderer/features/sessions/stores/sessionStore.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ const CLOUD_POLLING_INTERVAL_MS = 500;
3838
// Re-export for external consumers
3939
export type { PermissionRequest };
4040

41-
export type ExecutionMode = "plan" | "default" | "acceptEdits";
41+
export type ExecutionMode =
42+
| "plan"
43+
| "default"
44+
| "acceptEdits"
45+
| "bypassPermissions";
4246

4347
export interface AgentModelOption {
4448
modelId: string;
@@ -84,7 +88,7 @@ interface SessionActions {
8488
task: Task;
8589
repoPath: string;
8690
initialPrompt?: ContentBlock[];
87-
executionMode?: "plan" | "acceptEdits";
91+
executionMode?: "plan" | "acceptEdits" | "bypassPermissions";
8892
}) => Promise<void>;
8993
disconnectFromTask: (taskId: string) => Promise<void>;
9094
sendPrompt: (
@@ -495,7 +499,7 @@ function createBaseSession(
495499
taskRunId: string,
496500
taskId: string,
497501
isCloud: boolean,
498-
executionMode?: "plan" | "acceptEdits",
502+
executionMode?: "plan" | "acceptEdits" | "bypassPermissions",
499503
): AgentSession {
500504
return {
501505
taskRunId,
@@ -761,7 +765,7 @@ const useStore = create<SessionStore>()(
761765
repoPath: string,
762766
auth: AuthCredentials,
763767
initialPrompt?: ContentBlock[],
764-
executionMode?: "plan" | "acceptEdits",
768+
executionMode?: "plan" | "acceptEdits" | "bypassPermissions",
765769
) => {
766770
if (!auth.client) {
767771
throw new Error(

apps/twig/src/renderer/features/task-detail/components/TaskInput.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ import { SuggestedTasks } from "./SuggestedTasks";
1414
import { TaskInputEditor } from "./TaskInputEditor";
1515
import { type WorkspaceMode, WorkspaceModeSelect } from "./WorkspaceModeSelect";
1616

17-
const EXECUTION_MODES: ExecutionMode[] = ["plan", "default", "acceptEdits"];
17+
const EXECUTION_MODES: ExecutionMode[] = [
18+
"plan",
19+
"default",
20+
"acceptEdits",
21+
"bypassPermissions",
22+
];
1823

1924
function cycleMode(current: ExecutionMode): ExecutionMode {
2025
const currentIndex = EXECUTION_MODES.indexOf(current);

apps/twig/src/renderer/features/task-detail/hooks/useTaskCreation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ interface UseTaskCreationOptions {
2525
workspaceMode: WorkspaceMode;
2626
branch?: string | null;
2727
editorIsEmpty: boolean;
28-
executionMode?: "plan" | "acceptEdits";
28+
executionMode?: "plan" | "acceptEdits" | "bypassPermissions";
2929
}
3030

3131
interface UseTaskCreationReturn {
@@ -79,7 +79,7 @@ function prepareTaskInput(
7979
githubIntegrationId?: number;
8080
workspaceMode: WorkspaceMode;
8181
branch?: string | null;
82-
executionMode?: "plan" | "acceptEdits";
82+
executionMode?: "plan" | "acceptEdits" | "bypassPermissions";
8383
},
8484
): TaskCreationInput {
8585
return {

apps/twig/src/renderer/sagas/task/task-creation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ export interface TaskCreationInput {
3030
workspaceMode?: WorkspaceMode;
3131
branch?: string | null;
3232
githubIntegrationId?: number;
33-
// Execution mode: "plan" starts in plan mode (read-only), "acceptEdits" auto-approves edits, undefined starts in default mode
34-
executionMode?: "plan" | "acceptEdits";
33+
// Execution mode: "plan" starts in plan mode (read-only), "acceptEdits" auto-approves edits, "bypassPermissions" skips all permission prompts, undefined starts in default mode
34+
executionMode?: "plan" | "acceptEdits" | "bypassPermissions";
3535
}
3636

3737
export interface TaskCreationOutput {

0 commit comments

Comments
 (0)