From 5bb147b897c29ed6bbfdaaebd38fd08a90c19fb8 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 7 May 2026 17:12:35 -0700 Subject: [PATCH] Remove pty-output developer-permission detector (#1545) Co-authored-by: Orca --- .../developer-permission-hints.test.ts | 22 ------- .../developer-permission-hints.ts | 64 ------------------- .../terminal-pane/pty-connection.ts | 36 ----------- 3 files changed, 122 deletions(-) delete mode 100644 src/renderer/src/components/terminal-pane/developer-permission-hints.test.ts delete mode 100644 src/renderer/src/components/terminal-pane/developer-permission-hints.ts diff --git a/src/renderer/src/components/terminal-pane/developer-permission-hints.test.ts b/src/renderer/src/components/terminal-pane/developer-permission-hints.test.ts deleted file mode 100644 index d486dfc5afc..00000000000 --- a/src/renderer/src/components/terminal-pane/developer-permission-hints.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { detectDeveloperPermissionHint } from './developer-permission-hints' - -describe('detectDeveloperPermissionHint', () => { - it('detects microphone failures from terminal output', () => { - expect( - detectDeveloperPermissionHint('sox WARN coreaudio: default input device permission denied') - ?.permissionId - ).toBe('microphone') - }) - - it('detects screen recording failures from terminal output', () => { - expect( - detectDeveloperPermissionHint('screencapture failed: screen recording not authorized') - ?.permissionId - ).toBe('screen') - }) - - it('ignores unrelated permission text', () => { - expect(detectDeveloperPermissionHint('git: permission denied (publickey)')).toBeNull() - }) -}) diff --git a/src/renderer/src/components/terminal-pane/developer-permission-hints.ts b/src/renderer/src/components/terminal-pane/developer-permission-hints.ts deleted file mode 100644 index 4a79bace8cb..00000000000 --- a/src/renderer/src/components/terminal-pane/developer-permission-hints.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { DeveloperPermissionId } from '../../../../shared/developer-permissions-types' - -const ESC = String.fromCharCode(27) -const BEL = String.fromCharCode(7) -const ANSI_PATTERN = new RegExp( - `${ESC}(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~]|\\][^${BEL}]*(?:${BEL}|${ESC}\\\\))`, - 'g' -) - -type DeveloperPermissionHint = { - permissionId: DeveloperPermissionId - title: string - description: string -} - -export function detectDeveloperPermissionHint(data: string): DeveloperPermissionHint | null { - const normalized = data.slice(-4000).replace(ANSI_PATTERN, '').toLowerCase() - - if ( - /\b(microphone|audio input|input device|default input device)\b/.test(normalized) && - /\b(permission|denied|not authorized|unauthorized|no audio|not permitted)\b/.test(normalized) - ) { - return { - permissionId: 'microphone', - title: 'This command may need microphone access', - description: 'Open Developer Permissions to enable audio capture for terminal tools.' - } - } - - if ( - /\b(camera|webcam|video capture)\b/.test(normalized) && - /\b(permission|denied|not authorized|unauthorized|not permitted)\b/.test(normalized) - ) { - return { - permissionId: 'camera', - title: 'This command may need camera access', - description: 'Open Developer Permissions to enable camera capture for terminal tools.' - } - } - - if ( - /\b(screen recording|screen capture|screencapture|desktop capture)\b/.test(normalized) && - /\b(permission|denied|not authorized|unauthorized|not permitted)\b/.test(normalized) - ) { - return { - permissionId: 'screen', - title: 'This command may need screen recording access', - description: 'Open Developer Permissions to enable screenshots and screen capture.' - } - } - - if ( - /\b(apple events|osascript|system events|automation)\b/.test(normalized) && - /\b(not authorized|not allowed|permission|denied|not permitted)\b/.test(normalized) - ) { - return { - permissionId: 'automation', - title: 'This command may need automation access', - description: 'Open Developer Permissions to allow Apple Events for terminal scripts.' - } - } - - return null -} diff --git a/src/renderer/src/components/terminal-pane/pty-connection.ts b/src/renderer/src/components/terminal-pane/pty-connection.ts index a9785f4ec28..79ca4411885 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection.ts @@ -19,11 +19,9 @@ import { POST_REPLAY_FOCUS_REPORTING_RESET } from './layout-serialization' import { warnTerminalLifecycleAnomaly } from './terminal-lifecycle-diagnostics' -import { detectDeveloperPermissionHint } from './developer-permission-hints' import { registerPtySerializer, registerPtyTitleSource } from './pty-buffer-serializer' const pendingSpawnByPaneKey = new Map>() -const developerPermissionHintKeys = new Set() // Why: when multiple panes/tabs need the same deferred SSH connection, // the first one calls ssh.connect() and subsequent ones must wait for it @@ -90,38 +88,6 @@ function isSessionOwnedByWorktree(sessionId: string, worktreeId: string): boolea return sessionId.slice(0, separatorIdx) === worktreeId } -function maybeShowDeveloperPermissionHint(worktreeId: string, data: string): void { - if (!navigator.userAgent.includes('Mac')) { - return - } - - const hint = detectDeveloperPermissionHint(data) - if (!hint) { - return - } - const key = `${worktreeId}:${hint.permissionId}` - if (developerPermissionHintKeys.has(key)) { - return - } - developerPermissionHintKeys.add(key) - - toast.message(hint.title, { - description: hint.description, - duration: 12000, - action: { - label: 'Open Permissions', - onClick: () => { - useAppStore.getState().openSettingsTarget({ - pane: 'developer-permissions', - repoId: null, - sectionId: 'developer-permissions' - }) - useAppStore.getState().openSettingsPage() - } - } - }) -} - export function connectPanePty( pane: ManagedPane, manager: PaneManager, @@ -652,8 +618,6 @@ export function connectPanePty( } const dataCallback = (data: string): void => { - maybeShowDeveloperPermissionHint(deps.worktreeId, data) - if (deps.isVisibleRef.current) { pane.terminal.write(data) } else {