fix(ssh): open external host images from terminal links (#10323)

* fix(ssh): open external host images from terminal links

* fix(ssh): keep external file ownership host-scoped

* fix(ssh): reject blank external file owners

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
Jinwoo Hong
2026-07-24 12:05:38 -07:00
committed by GitHub
co-authored by OrcaWin
parent 3dfbb10775
commit 01929fde40
31 changed files with 785 additions and 18 deletions
+2
View File
@@ -1066,6 +1066,8 @@ export type PersistedOpenFile = {
language: string
isPreview?: boolean
runtimeEnvironmentId?: string | null
/** SSH target that owns an absolute path outside the worktree. */
externalSshTargetId?: string
/** Unsaved editor buffer captured for hot exit; presence restores the tab dirty. */
dirtyDraftContent?: string
/** Signature of the disk content the dirty draft is based on; lets restore
@@ -14,6 +14,55 @@ describe('parseWorkspaceSession', () => {
expect(result.ok).toBe(true)
})
it('preserves external SSH file ownership across session parsing', () => {
const result = parseWorkspaceSession({
activeRepoId: null,
activeWorktreeId: 'wt',
activeTabId: null,
tabsByWorktree: {},
terminalLayoutsByTabId: {},
openFilesByWorktree: {
wt: [
{
filePath: '/tmp/external.png',
relativePath: '/tmp/external.png',
worktreeId: 'wt',
language: 'png',
externalSshTargetId: 'ssh-1'
}
]
}
})
expect(result.ok).toBe(true)
if (result.ok) {
expect(result.value.openFilesByWorktree?.wt?.[0]?.externalSshTargetId).toBe('ssh-1')
}
})
it('rejects blank external SSH file ownership', () => {
const result = parseWorkspaceSession({
activeRepoId: null,
activeWorktreeId: 'wt',
activeTabId: null,
tabsByWorktree: {},
terminalLayoutsByTabId: {},
openFilesByWorktree: {
wt: [
{
filePath: '/tmp/external.png',
relativePath: '/tmp/external.png',
worktreeId: 'wt',
language: 'png',
externalSshTargetId: ' '
}
]
}
})
expect(result.ok).toBe(false)
})
it('accepts a fully populated session with optional fields', () => {
const result = parseWorkspaceSession({
activeRepoId: 'repo1',
+1
View File
@@ -161,6 +161,7 @@ const persistedOpenFileSchema = z.object({
language: z.string(),
isPreview: z.boolean().optional(),
runtimeEnvironmentId: z.string().nullable().optional(),
externalSshTargetId: z.string().trim().min(1).optional(),
dirtyDraftContent: z.string().optional(),
lastKnownDiskSignature: z.string().optional(),
readOnly: z.boolean().optional(),