Skip to content

Commit 9421160

Browse files
committed
Pass permission mode through session resume and creation
lint
1 parent bf2ef9c commit 9421160

5 files changed

Lines changed: 29 additions & 2 deletions

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export const sessionConfigSchema = z.object({
2525
adapter: z.enum(["claude", "codex"]).optional(),
2626
/** Additional directories Claude can access beyond cwd (for worktree support) */
2727
additionalDirectories: z.array(z.string()).optional(),
28+
/** Permission mode to use for the session (e.g. "default", "acceptEdits", "plan", "bypassPermissions") */
29+
permissionMode: z.string().optional(),
2830
});
2931

3032
export type SessionConfig = z.infer<typeof sessionConfigSchema>;
@@ -157,6 +159,7 @@ export const reconnectSessionInput = z.object({
157159
adapter: z.enum(["claude", "codex"]).optional(),
158160
/** Additional directories Claude can access beyond cwd (for worktree support) */
159161
additionalDirectories: z.array(z.string()).optional(),
162+
permissionMode: z.string().optional(),
160163
});
161164

162165
export type ReconnectSessionInput = z.infer<typeof reconnectSessionInput>;

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ interface SessionConfig {
176176
adapter?: "claude" | "codex";
177177
/** Additional directories Claude can access beyond cwd (for worktree support) */
178178
additionalDirectories?: string[];
179+
/** Permission mode to use for the session */
180+
permissionMode?: string;
179181
}
180182

181183
interface ManagedSession {
@@ -420,6 +422,7 @@ export class AgentService extends TypedEventEmitter<AgentServiceEvents> {
420422
sessionId: existingSessionId,
421423
adapter,
422424
additionalDirectories,
425+
permissionMode,
423426
} = config;
424427

425428
if (!isRetry) {
@@ -538,6 +541,7 @@ export class AgentService extends TypedEventEmitter<AgentServiceEvents> {
538541
taskRunId,
539542
...(existingSessionId && { sessionId: existingSessionId }),
540543
systemPrompt,
544+
...(permissionMode && { permissionMode }),
541545
...(additionalDirectories?.length && {
542546
claudeCode: {
543547
options: { additionalDirectories },
@@ -561,6 +565,7 @@ export class AgentService extends TypedEventEmitter<AgentServiceEvents> {
561565
_meta: {
562566
taskRunId,
563567
systemPrompt,
568+
...(permissionMode && { permissionMode }),
564569
...(additionalDirectories?.length && {
565570
claudeCode: {
566571
options: { additionalDirectories },
@@ -1279,6 +1284,8 @@ For git operations while detached:
12791284
"additionalDirectories" in params
12801285
? params.additionalDirectories
12811286
: undefined,
1287+
permissionMode:
1288+
"permissionMode" in params ? params.permissionMode : undefined,
12821289
};
12831290
}
12841291

apps/twig/src/renderer/features/sessions/service/service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,11 @@ export class SessionService {
275275
this.subscribeToChannel(taskRunId);
276276

277277
try {
278+
const persistedMode = getConfigOptionByCategory(
279+
persistedConfigOptions,
280+
"mode",
281+
)?.currentValue;
282+
278283
const result = await trpcVanilla.agent.reconnect.mutate({
279284
taskId,
280285
taskRunId,
@@ -285,6 +290,7 @@ export class SessionService {
285290
logUrl,
286291
sessionId,
287292
adapter: resolvedAdapter,
293+
permissionMode: persistedMode,
288294
});
289295

290296
if (result) {

packages/agent/src/adapters/claude/claude-agent.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
138138

139139
const meta = params._meta as NewSessionMeta | undefined;
140140
const internalSessionId = uuidv7();
141-
const permissionMode: TwigExecutionMode = "default";
141+
const permissionMode: TwigExecutionMode =
142+
meta?.permissionMode &&
143+
TWIG_EXECUTION_MODES.includes(meta.permissionMode as TwigExecutionMode)
144+
? (meta.permissionMode as TwigExecutionMode)
145+
: "default";
142146

143147
const mcpServers = parseMcpServers(params);
144148
await fetchMcpToolMetadata(mcpServers, this.logger);
@@ -203,10 +207,16 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
203207
const mcpServers = parseMcpServers(params);
204208
await fetchMcpToolMetadata(mcpServers, this.logger);
205209

210+
const permissionMode: TwigExecutionMode =
211+
meta?.permissionMode &&
212+
TWIG_EXECUTION_MODES.includes(meta.permissionMode as TwigExecutionMode)
213+
? (meta.permissionMode as TwigExecutionMode)
214+
: "default";
215+
206216
const { query: q, session } = await this.initializeQuery({
207217
internalSessionId,
208218
cwd: params.cwd,
209-
permissionMode: "default",
219+
permissionMode,
210220
mcpServers,
211221
systemPrompt: buildSystemPrompt(meta?.systemPrompt),
212222
userProvidedOptions: meta?.claudeCode?.options,

packages/agent/src/adapters/claude/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export type NewSessionMeta = {
5555
disableBuiltInTools?: boolean;
5656
systemPrompt?: unknown;
5757
sessionId?: string;
58+
permissionMode?: string;
5859
claudeCode?: {
5960
options?: Options;
6061
};

0 commit comments

Comments
 (0)