feat: harden local shell, SFTP, and desktop session reliability
Finder-launched terminals now inherit a login PATH so tools like ollama resolve, destructive SFTP/editor actions require confirmation, and terminal search plus window dragging work again. SSH forwards and RDP sessions keep listeners and survive reconnect without FastPath crashes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
188f3556ed
commit
08696896f9
223 files changed
+13493
-3423
No files matched your search
@@ -32,4 +32,26 @@ describe('native connection close', () => {
|
||||
expect(clearIntervalSpy).toHaveBeenCalled()
|
||||
clearIntervalSpy.mockRestore()
|
||||
})
|
||||
|
||||
it('keeps tunnel listeners when the pooled SSH connection is reconnecting', async () => {
|
||||
const disconnect = window.opsxApi?.sshDisconnect as ReturnType<typeof vi.fn>
|
||||
disconnect.mockClear()
|
||||
usePoolStore.setState({ connections: new Map([['conn-1', connection('conn-1')]]) })
|
||||
|
||||
await usePoolStore.getState().disconnectConnection('conn-1', 'auto reconnect cleanup', {
|
||||
retainForwards: true,
|
||||
})
|
||||
|
||||
expect(disconnect).toHaveBeenCalledWith('conn-1', { retainForwards: true })
|
||||
})
|
||||
|
||||
it('stops tunnel listeners when the last tab releases the pooled SSH connection', async () => {
|
||||
const disconnect = window.opsxApi?.sshDisconnect as ReturnType<typeof vi.fn>
|
||||
disconnect.mockClear()
|
||||
usePoolStore.setState({ connections: new Map([['conn-1', connection('conn-1')]]) })
|
||||
|
||||
await usePoolStore.getState().disconnectConnection('conn-1', 'no refs')
|
||||
|
||||
expect(disconnect).toHaveBeenCalledWith('conn-1', { retainForwards: false })
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,43 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import { useTabStore } from '../../src/stores/tabStore'
|
||||
import { rewriteTabConnectionIds } from '../../src/stores/connection/rewriteTabs'
|
||||
|
||||
describe('rewriteTabConnectionIds', () => {
|
||||
beforeEach(() => {
|
||||
useTabStore.setState({ tabs: [], activeTabId: null })
|
||||
})
|
||||
|
||||
it('remaps connectionInstance ids across tabs', () => {
|
||||
useTabStore.setState({
|
||||
tabs: [
|
||||
{
|
||||
id: 't1',
|
||||
title: 'a',
|
||||
type: 'terminal',
|
||||
connectionInstance: { connectionId: 'old', shellId: 's1' },
|
||||
} as never,
|
||||
{
|
||||
id: 't2',
|
||||
title: 'b',
|
||||
type: 'sftp',
|
||||
connectionInstance: { connectionId: 'old', sftpId: 'f1' },
|
||||
} as never,
|
||||
{
|
||||
id: 't3',
|
||||
title: 'c',
|
||||
type: 'terminal',
|
||||
connectionInstance: { connectionId: 'other', shellId: 's2' },
|
||||
} as never,
|
||||
],
|
||||
activeTabId: 't1',
|
||||
})
|
||||
|
||||
rewriteTabConnectionIds('old', 'new')
|
||||
|
||||
const tabs = useTabStore.getState().tabs
|
||||
expect(tabs[0].connectionInstance?.connectionId).toBe('new')
|
||||
expect(tabs[1].connectionInstance?.connectionId).toBe('new')
|
||||
expect(tabs[2].connectionInstance?.connectionId).toBe('other')
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user