mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
Remove pty-output developer-permission detector (#1545)
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -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()
|
||||
})
|
||||
})
|
||||
@@ -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
|
||||
}
|
||||
@@ -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<string, Promise<string | null>>()
|
||||
const developerPermissionHintKeys = new Set<string>()
|
||||
|
||||
// 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 {
|
||||
|
||||
Reference in New Issue
Block a user