Files
Codeman/test/claude-permission-mode.test.ts
Codeman maintainer 91070f5dda feat(claude): add 'auto' startup permission mode
Adds Anthropic's classifier-guarded low-prompt mode (--permission-mode
auto) as a fourth ClaudeMode alongside skip-permissions/normal/allowedTools.
Wired through both spawn paths (buildPermissionArgs for direct PTY,
buildClaudePermissionFlags for tmux), the getClaudeModeConfig validator,
and the App Settings Startup Mode picker. Exports buildSpawnCommand for
test coverage.

This is the prerequisite for multi-user mode section 6.3, which downgrades
non-granted users' sessions to 'auto'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 02:48:14 +02:00

84 lines
3.8 KiB
TypeScript

/**
* @fileoverview Tests for Claude CLI startup permission modes, focused on the
* 'auto' mode (`--permission-mode auto`, Anthropic's recommended low-prompt mode)
* added alongside the default `--dangerously-skip-permissions`.
*
* Covers BOTH spawn paths, which build the permission flags independently:
* - session-cli-builder.buildInteractiveArgs (direct PTY, non-mux fallback)
* - tmux-manager.buildSpawnCommand (tmux pane command string)
* The default must stay 'dangerously-skip-permissions' when the setting is unset.
*/
import { describe, it, expect } from 'vitest';
import { buildInteractiveArgs } from '../src/session-cli-builder.js';
import { buildSpawnCommand } from '../src/tmux-manager.js';
describe('buildInteractiveArgs permission modes (direct PTY path)', () => {
it('keeps --dangerously-skip-permissions as the skip-mode flag', () => {
const args = buildInteractiveArgs('sid-1', 'dangerously-skip-permissions');
expect(args).toContain('--dangerously-skip-permissions');
expect(args).not.toContain('--permission-mode');
});
it('auto mode emits --permission-mode auto and never the skip flag', () => {
const args = buildInteractiveArgs('sid-1', 'auto');
const idx = args.indexOf('--permission-mode');
expect(idx).toBeGreaterThanOrEqual(0);
expect(args[idx + 1]).toBe('auto');
expect(args).not.toContain('--dangerously-skip-permissions');
});
it('normal mode emits no permission flag at all', () => {
const args = buildInteractiveArgs('sid-1', 'normal');
expect(args).not.toContain('--dangerously-skip-permissions');
expect(args).not.toContain('--permission-mode');
});
it('allowedTools mode is unchanged by the auto addition', () => {
const args = buildInteractiveArgs('sid-1', 'allowedTools', undefined, 'Read,Grep');
expect(args).toEqual(expect.arrayContaining(['--allowedTools', 'Read,Grep']));
expect(args).not.toContain('--permission-mode');
});
it('auto mode composes with model and effort flags', () => {
const args = buildInteractiveArgs('sid-1', 'auto', 'opus', undefined, 'high');
expect(args).toEqual(expect.arrayContaining(['--permission-mode', 'auto', '--model', 'opus', '--effort', 'high']));
});
});
describe('buildSpawnCommand permission modes (tmux path)', () => {
it('unset claudeMode defaults to --dangerously-skip-permissions', () => {
const cmd = buildSpawnCommand({ mode: 'claude', sessionId: 'sid-1' });
expect(cmd).toContain('claude --dangerously-skip-permissions --session-id "sid-1"');
expect(cmd).not.toContain('--permission-mode');
});
it('auto mode emits --permission-mode auto and never the skip flag', () => {
const cmd = buildSpawnCommand({ mode: 'claude', sessionId: 'sid-1', claudeMode: 'auto' });
expect(cmd).toContain('claude --permission-mode auto --session-id "sid-1"');
expect(cmd).not.toContain('--dangerously-skip-permissions');
});
it('auto mode carries into BOTH legs of the resume fallback command', () => {
const cmd = buildSpawnCommand({
mode: 'claude',
sessionId: 'sid-1',
claudeMode: 'auto',
resumeSessionId: 'abc-123',
});
const [resumeLeg, fallbackLeg] = cmd.split('||');
expect(resumeLeg).toContain('--permission-mode auto');
expect(resumeLeg).toContain('--resume "abc-123"');
expect(fallbackLeg).toContain('--permission-mode auto');
expect(fallbackLeg).toContain('--session-id "sid-1"');
expect(cmd).not.toContain('--dangerously-skip-permissions');
});
it('normal mode emits no permission flag', () => {
const cmd = buildSpawnCommand({ mode: 'claude', sessionId: 'sid-1', claudeMode: 'normal' });
expect(cmd).toContain('claude --session-id "sid-1"');
expect(cmd).not.toContain('--permission-mode');
expect(cmd).not.toContain('--dangerously-skip-permissions');
});
});