From b597a680348ce664cc1f3bbf923851863fbce4c6 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Tue, 10 Feb 2026 15:06:43 +0000 Subject: [PATCH] Pass permission mode through session resume and creation lint --- apps/twig/src/main/services/agent/schemas.ts | 3 +++ apps/twig/src/main/services/agent/service.ts | 7 +++++++ .../renderer/features/sessions/service/service.ts | 6 ++++++ packages/agent/src/adapters/claude/claude-agent.ts | 14 ++++++++++++-- packages/agent/src/adapters/claude/types.ts | 1 + 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/apps/twig/src/main/services/agent/schemas.ts b/apps/twig/src/main/services/agent/schemas.ts index 837618734..6d8b7619a 100644 --- a/apps/twig/src/main/services/agent/schemas.ts +++ b/apps/twig/src/main/services/agent/schemas.ts @@ -25,6 +25,8 @@ export const sessionConfigSchema = z.object({ adapter: z.enum(["claude", "codex"]).optional(), /** Additional directories Claude can access beyond cwd (for worktree support) */ additionalDirectories: z.array(z.string()).optional(), + /** Permission mode to use for the session (e.g. "default", "acceptEdits", "plan", "bypassPermissions") */ + permissionMode: z.string().optional(), }); export type SessionConfig = z.infer; @@ -157,6 +159,7 @@ export const reconnectSessionInput = z.object({ adapter: z.enum(["claude", "codex"]).optional(), /** Additional directories Claude can access beyond cwd (for worktree support) */ additionalDirectories: z.array(z.string()).optional(), + permissionMode: z.string().optional(), }); export type ReconnectSessionInput = z.infer; diff --git a/apps/twig/src/main/services/agent/service.ts b/apps/twig/src/main/services/agent/service.ts index 5cd70caa1..1011413c8 100644 --- a/apps/twig/src/main/services/agent/service.ts +++ b/apps/twig/src/main/services/agent/service.ts @@ -176,6 +176,8 @@ interface SessionConfig { adapter?: "claude" | "codex"; /** Additional directories Claude can access beyond cwd (for worktree support) */ additionalDirectories?: string[]; + /** Permission mode to use for the session */ + permissionMode?: string; } interface ManagedSession { @@ -420,6 +422,7 @@ export class AgentService extends TypedEventEmitter { sessionId: existingSessionId, adapter, additionalDirectories, + permissionMode, } = config; if (!isRetry) { @@ -538,6 +541,7 @@ export class AgentService extends TypedEventEmitter { taskRunId, ...(existingSessionId && { sessionId: existingSessionId }), systemPrompt, + ...(permissionMode && { permissionMode }), ...(additionalDirectories?.length && { claudeCode: { options: { additionalDirectories }, @@ -561,6 +565,7 @@ export class AgentService extends TypedEventEmitter { _meta: { taskRunId, systemPrompt, + ...(permissionMode && { permissionMode }), ...(additionalDirectories?.length && { claudeCode: { options: { additionalDirectories }, @@ -1279,6 +1284,8 @@ For git operations while detached: "additionalDirectories" in params ? params.additionalDirectories : undefined, + permissionMode: + "permissionMode" in params ? params.permissionMode : undefined, }; } diff --git a/apps/twig/src/renderer/features/sessions/service/service.ts b/apps/twig/src/renderer/features/sessions/service/service.ts index e236c9220..d669745ae 100644 --- a/apps/twig/src/renderer/features/sessions/service/service.ts +++ b/apps/twig/src/renderer/features/sessions/service/service.ts @@ -275,6 +275,11 @@ export class SessionService { this.subscribeToChannel(taskRunId); try { + const persistedMode = getConfigOptionByCategory( + persistedConfigOptions, + "mode", + )?.currentValue; + const result = await trpcVanilla.agent.reconnect.mutate({ taskId, taskRunId, @@ -285,6 +290,7 @@ export class SessionService { logUrl, sessionId, adapter: resolvedAdapter, + permissionMode: persistedMode, }); if (result) { diff --git a/packages/agent/src/adapters/claude/claude-agent.ts b/packages/agent/src/adapters/claude/claude-agent.ts index f01c2d63b..871cf262e 100644 --- a/packages/agent/src/adapters/claude/claude-agent.ts +++ b/packages/agent/src/adapters/claude/claude-agent.ts @@ -138,7 +138,11 @@ export class ClaudeAcpAgent extends BaseAcpAgent { const meta = params._meta as NewSessionMeta | undefined; const internalSessionId = uuidv7(); - const permissionMode: TwigExecutionMode = "default"; + const permissionMode: TwigExecutionMode = + meta?.permissionMode && + TWIG_EXECUTION_MODES.includes(meta.permissionMode as TwigExecutionMode) + ? (meta.permissionMode as TwigExecutionMode) + : "default"; const mcpServers = parseMcpServers(params); await fetchMcpToolMetadata(mcpServers, this.logger); @@ -203,10 +207,16 @@ export class ClaudeAcpAgent extends BaseAcpAgent { const mcpServers = parseMcpServers(params); await fetchMcpToolMetadata(mcpServers, this.logger); + const permissionMode: TwigExecutionMode = + meta?.permissionMode && + TWIG_EXECUTION_MODES.includes(meta.permissionMode as TwigExecutionMode) + ? (meta.permissionMode as TwigExecutionMode) + : "default"; + const { query: q, session } = await this.initializeQuery({ internalSessionId, cwd: params.cwd, - permissionMode: "default", + permissionMode, mcpServers, systemPrompt: buildSystemPrompt(meta?.systemPrompt), userProvidedOptions: meta?.claudeCode?.options, diff --git a/packages/agent/src/adapters/claude/types.ts b/packages/agent/src/adapters/claude/types.ts index b99b78f70..3eefa885d 100644 --- a/packages/agent/src/adapters/claude/types.ts +++ b/packages/agent/src/adapters/claude/types.ts @@ -55,6 +55,7 @@ export type NewSessionMeta = { disableBuiltInTools?: boolean; systemPrompt?: unknown; sessionId?: string; + permissionMode?: string; claudeCode?: { options?: Options; };