mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 17:47:40 +00:00
refactor(renderer): fold four lib callers off the deprecated runtime-owner resolver (#30458)
Open-in owner, execution-host platform facts, doc-preview grants and the activation PTY inventory read the owner through resolveOwnerWithLegacyFallback. Open in now refuses a twin instead of launching it as this desktop's checkout; the others keep reading a twin as not server-owned. A row whose only repo row is a server proxying its SSH target routes through that server. The creation-action policy stays until browser creation folds with it. Deprecated importers 57 -> 53.
This commit is contained in:
@@ -34,9 +34,7 @@ src/renderer/src/lib/active-agent-note-send.ts
|
||||
src/renderer/src/lib/active-agent-note-target.ts
|
||||
src/renderer/src/lib/agent-hibernation-coordinator.ts
|
||||
src/renderer/src/lib/client-creation-action-policy.ts
|
||||
src/renderer/src/lib/doc-preview-grants.ts
|
||||
src/renderer/src/lib/execute-open-editor-path-move.ts
|
||||
src/renderer/src/lib/execution-host-facts.ts
|
||||
src/renderer/src/lib/file-preview.ts
|
||||
src/renderer/src/lib/launch-agent-background-session.ts
|
||||
src/renderer/src/lib/launch-agent-in-new-tab.ts
|
||||
@@ -47,10 +45,8 @@ src/renderer/src/lib/terminal-tab-owner-activation.ts
|
||||
src/renderer/src/lib/terminal-worktree-route.ts
|
||||
src/renderer/src/lib/web-runtime-worktree-terminal-after-wake.ts
|
||||
src/renderer/src/lib/workspace-tab-palette-activation.ts
|
||||
src/renderer/src/lib/worktree-activation-pty-inventory.ts
|
||||
src/renderer/src/lib/worktree-activation.ts
|
||||
src/renderer/src/lib/worktree-creation-agent-seeds.ts
|
||||
src/renderer/src/lib/worktree-row-open-in-owner.ts
|
||||
src/renderer/src/lib/worktree-sort-order-host-split.ts
|
||||
src/renderer/src/store/slices/browser/browser-page-conversion-actions.ts
|
||||
src/renderer/src/store/slices/browser/browser-tab-actions.ts
|
||||
|
||||
@@ -164,7 +164,6 @@
|
||||
1 src/renderer/src/components/sidebar/WorkspaceKanbanDrawer.tsx
|
||||
1 src/renderer/src/components/sidebar/WorktreeCardPorts.tsx
|
||||
2 src/renderer/src/components/sidebar/WorktreeList.tsx
|
||||
1 src/renderer/src/components/sidebar/WorktreeRowOpenInSubMenu.tsx
|
||||
1 src/renderer/src/components/sidebar/WorktreeVisibilityDialog.tsx
|
||||
2 src/renderer/src/components/sidebar/delete-worktree-flow.ts
|
||||
1 src/renderer/src/components/sidebar/linear-agent-skill-runtime.ts
|
||||
@@ -312,11 +311,10 @@
|
||||
1 src/renderer/src/lib/client-creation-action-error.ts
|
||||
3 src/renderer/src/lib/client-creation-action-policy.ts
|
||||
1 src/renderer/src/lib/default-creation-host.ts # the sanctioned reader of the default host
|
||||
1 src/renderer/src/lib/doc-preview-grants.ts
|
||||
1 src/renderer/src/lib/empty-workspace-default-agent-chat.ts
|
||||
3 src/renderer/src/lib/execute-open-editor-path-move.ts
|
||||
1 src/renderer/src/lib/execution-host-display-label.ts
|
||||
2 src/renderer/src/lib/execution-host-facts.ts
|
||||
1 src/renderer/src/lib/execution-host-facts.ts
|
||||
6 src/renderer/src/lib/file-preview.ts
|
||||
2 src/renderer/src/lib/folder-workspace-runtime-owner.ts
|
||||
6 src/renderer/src/lib/http-link-destinations.ts
|
||||
@@ -351,12 +349,10 @@
|
||||
5 src/renderer/src/lib/workspace-browser-tab-open.ts
|
||||
1 src/renderer/src/lib/workspace-file-drag-source.ts
|
||||
1 src/renderer/src/lib/workspace-tab-palette-activation.ts
|
||||
1 src/renderer/src/lib/worktree-activation-pty-inventory.ts
|
||||
3 src/renderer/src/lib/worktree-activation.ts
|
||||
1 src/renderer/src/lib/worktree-creation-agent-seeds.ts
|
||||
1 src/renderer/src/lib/worktree-jump-navigation.ts
|
||||
2 src/renderer/src/lib/worktree-operation-route.ts
|
||||
1 src/renderer/src/lib/worktree-row-open-in-owner.ts
|
||||
7 src/renderer/src/lib/worktree-runtime-owner.ts # typed owner resolver, its null-collapsing wrapper, and the legacy-fallback adapter the folds move to (round 3 F0); deleting the deprecated pair (F8) nets it down
|
||||
1 src/renderer/src/lib/worktree-sort-order-host-split.ts
|
||||
1 src/renderer/src/runtime/local-structured-session-tabs-sync/snapshot-apply.ts
|
||||
|
||||
+2
-1
@@ -22,7 +22,8 @@ vi.mock('@/lib/connection-owner-resolution', async (importOriginal) => ({
|
||||
}))
|
||||
vi.mock('@/lib/worktree-runtime-owner', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof WorktreeRuntimeOwnerModule>()),
|
||||
getRuntimeEnvironmentIdForWorktree: () => 'env-1'
|
||||
getRuntimeEnvironmentIdForWorktree: () => 'env-1',
|
||||
runtimeEnvironmentIdWithLegacyFallbackUnlessTwin: () => 'env-1'
|
||||
}))
|
||||
|
||||
import { NativeChatInlineVisual } from './NativeChatInlineVisual'
|
||||
|
||||
@@ -3,6 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
const mocks = vi.hoisted(() => ({
|
||||
connectionId: null as string | null | undefined,
|
||||
environmentId: null as string | null,
|
||||
ambiguous: false,
|
||||
mintGrant: vi.fn(),
|
||||
revokeGrant: vi.fn()
|
||||
}))
|
||||
@@ -11,7 +12,8 @@ vi.mock('@/lib/connection-owner-resolution', () => ({
|
||||
getConnectionIdForFileFromState: () => mocks.connectionId
|
||||
}))
|
||||
vi.mock('@/lib/worktree-runtime-owner', () => ({
|
||||
getRuntimeEnvironmentIdForWorktree: () => mocks.environmentId
|
||||
runtimeEnvironmentIdWithLegacyFallbackUnlessTwin: () =>
|
||||
mocks.ambiguous ? null : mocks.environmentId
|
||||
}))
|
||||
|
||||
import {
|
||||
@@ -26,6 +28,7 @@ beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mocks.connectionId = null
|
||||
mocks.environmentId = null
|
||||
mocks.ambiguous = false
|
||||
mocks.mintGrant.mockResolvedValue({ grantId: 'grant-1', url: 'orca-preview://grant-1/a.html' })
|
||||
vi.stubGlobal('window', {
|
||||
api: { docPreview: { mintGrant: mocks.mintGrant, revokeGrant: mocks.revokeGrant } }
|
||||
@@ -33,6 +36,11 @@ beforeEach(() => {
|
||||
})
|
||||
|
||||
describe('buildDocPreviewGrantRequest', () => {
|
||||
it('mints no grant for a twin, which names no server to mint against', () => {
|
||||
mocks.ambiguous = true
|
||||
expect(buildDocPreviewGrantRequest(state, 'wt-1', '/srv/repo/docs/a.html')).toBeNull()
|
||||
})
|
||||
|
||||
// A document outside every workspace resolves and authorizes from its own directory.
|
||||
it('roots an SSH grant outside the workspace at the document directory', () => {
|
||||
mocks.connectionId = 'ssh-1'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { DocPreviewGrantRequest } from '../../../preload/api/doc-preview-api'
|
||||
import { basename, dirname, getRelativePathInsideRoot } from '@/lib/path'
|
||||
import { getConnectionIdForFileFromState } from '@/lib/connection-owner-resolution'
|
||||
import { getRuntimeEnvironmentIdForWorktree } from '@/lib/worktree-runtime-owner'
|
||||
import { runtimeEnvironmentIdWithLegacyFallbackUnlessTwin } from '@/lib/worktree-runtime-owner'
|
||||
import { toRuntimeWorktreeSelector } from '@/runtime/runtime-worktree-selector'
|
||||
import { chatScratchFileAddress } from '@/runtime/runtime-chat-scratch-file-address'
|
||||
import type { AppState } from '@/store/types'
|
||||
@@ -43,7 +43,8 @@ export function buildDocPreviewGrantRequest(
|
||||
// directory is often a home directory, which is where secrets live.
|
||||
return { owner: { kind: 'ssh', connectionId }, requestBase, root, entryRelativePath }
|
||||
}
|
||||
const environmentId = getRuntimeEnvironmentIdForWorktree(state, worktreeId)
|
||||
// Why: a twin names no server to mint against, so it gets no grant.
|
||||
const environmentId = runtimeEnvironmentIdWithLegacyFallbackUnlessTwin(state, worktreeId)
|
||||
// Outside the workspace, a chat's scratch folder stands in for it: its host serves it as a root.
|
||||
const base =
|
||||
worktreeRoot && worktreeRelativePath
|
||||
|
||||
@@ -14,7 +14,7 @@ import { getLocalProjectExecutionRuntimeContext } from './local-preflight-contex
|
||||
import { CLIENT_PLATFORM } from './new-workspace'
|
||||
import {
|
||||
getExecutionHostIdForWorktree,
|
||||
getRuntimeEnvironmentIdForWorktree
|
||||
runtimeEnvironmentIdWithLegacyFallbackUnlessTwin
|
||||
} from './worktree-runtime-owner'
|
||||
|
||||
/**
|
||||
@@ -148,7 +148,9 @@ export function resolveWorktreeExecutionHostPlatform(
|
||||
nestedSshTargetId:
|
||||
host?.kind === 'runtime' ? (getConnectionIdFromState(state, worktreeId) ?? null) : null,
|
||||
sshOwnerEnvironmentId:
|
||||
host?.kind === 'ssh' ? getRuntimeEnvironmentIdForWorktree(state, worktreeId) : null,
|
||||
host?.kind === 'ssh'
|
||||
? runtimeEnvironmentIdWithLegacyFallbackUnlessTwin(state, worktreeId)
|
||||
: null,
|
||||
workspacePath,
|
||||
projectRuntime: () => getLocalProjectExecutionRuntimeContext(state, worktreeId)
|
||||
})
|
||||
|
||||
@@ -178,7 +178,8 @@ vi.mock('@/runtime/local-runtime-capabilities', () => ({
|
||||
vi.mock('@/lib/worktree-runtime-owner', () => ({
|
||||
getExecutionHostIdForWorktree: () =>
|
||||
store.repos[0]?.connectionId ? `ssh:${store.repos[0].connectionId}` : 'local',
|
||||
getRuntimeEnvironmentIdForWorktree: () => null
|
||||
getRuntimeEnvironmentIdForWorktree: () => null,
|
||||
runtimeEnvironmentIdWithLegacyFallbackUnlessTwin: () => null
|
||||
}))
|
||||
vi.mock('@/runtime/structured-agent-session-client', () => ({
|
||||
callStructuredAgentSession: (target: unknown, method: string, params: unknown) =>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { FLOATING_TERMINAL_WORKTREE_ID } from '../../../shared/constants'
|
||||
import { parseExecutionHostId } from '../../../shared/execution-host'
|
||||
import type { PtyListedSession, PtySessionListScope } from '../../../shared/pty-listed-session'
|
||||
import { getRepoIdFromWorktreeId } from '../../../shared/worktree/id'
|
||||
import { getRuntimeEnvironmentIdForWorktree } from './worktree-runtime-owner'
|
||||
import { runtimeEnvironmentIdWithLegacyFallbackUnlessTwin } from './worktree-runtime-owner'
|
||||
import {
|
||||
resolveIndexedRepoOwner,
|
||||
resolveIndexedWorktreeOwner
|
||||
@@ -21,7 +21,10 @@ export function resolveActivationPtyListScope(
|
||||
return { connectionId: null }
|
||||
}
|
||||
const resolution = resolveWorktreeOperationRouteResult(state, worktreeId)
|
||||
if (resolution.kind === 'missing' && !getRuntimeEnvironmentIdForWorktree(state, worktreeId)) {
|
||||
if (
|
||||
resolution.kind === 'missing' &&
|
||||
!runtimeEnvironmentIdWithLegacyFallbackUnlessTwin(state, worktreeId)
|
||||
) {
|
||||
const repo = resolveIndexedRepoOwner(state.repos, getRepoIdFromWorktreeId(worktreeId))
|
||||
const worktree = resolveIndexedWorktreeOwner(state.worktreesByRepo, worktreeId)
|
||||
// A known native repo remains usable while the unrelated runtime catalog hydrates.
|
||||
|
||||
@@ -3,6 +3,30 @@ import type { Worktree } from '../../../shared/worktree/types'
|
||||
import { resolveWorktreeRowOpenInRuntimeOwner } from './worktree-row-open-in-owner'
|
||||
import { getExternalEditorOpenCapability } from './external-editor-open-capability'
|
||||
import { getLocalPathOpenOwnerForRoute, isLocalPathOpenBlocked } from './local-path-open-guard'
|
||||
import { OWNER_RESOLUTION_CASES } from './runtime-owner-alias-matrix.test-fixture'
|
||||
|
||||
describe('an unhosted row resolves through the fold adapter', () => {
|
||||
const caseState = (name: string) => OWNER_RESOLUTION_CASES.find((c) => c.name === name)!.state
|
||||
const row = (id: string, repoId: string) => ({ id, repoId, hostId: undefined })
|
||||
|
||||
it('leaves a git twin unresolved instead of launching it as this desktop checkout', () => {
|
||||
expect(
|
||||
resolveWorktreeRowOpenInRuntimeOwner(
|
||||
caseState('focused | projected-twin::wt'),
|
||||
row('projected-twin::wt', 'projected-twin')
|
||||
).ownerUnresolved
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
it('routes a row whose only repo row is a server proxying its target through that server', () => {
|
||||
expect(
|
||||
resolveWorktreeRowOpenInRuntimeOwner(
|
||||
caseState('focused | stale-hub-repo::wt'),
|
||||
row('stale-hub-repo::wt', 'stale-hub-repo')
|
||||
)
|
||||
).toEqual({ runtimeEnvironmentId: 'hub-env', connectionId: null, ownerUnresolved: false })
|
||||
})
|
||||
})
|
||||
|
||||
const WORKTREE_ID = 'repo-1::/srv/worktree'
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { parseExecutionHostId } from '../../../shared/execution-host'
|
||||
import type { Worktree } from '../../../shared/worktree/types'
|
||||
import { getResolvedExecutionHostIdForWorktree } from './resolved-worktree-execution-host'
|
||||
import { getRuntimeEnvironmentIdForWorktree } from './worktree-runtime-owner'
|
||||
import { resolveOwnerWithLegacyFallback } from './worktree-runtime-owner'
|
||||
import type { WorktreeRuntimeOwnerState } from './worktree-runtime-owner-state'
|
||||
import {
|
||||
resolveStrictWorktreeOperationRouteResultForHost,
|
||||
@@ -46,10 +45,17 @@ export function resolveWorktreeRowOpenInRuntimeOwner(
|
||||
return runtimeEnvironmentId ? resolved(runtimeEnvironmentId) : UNRESOLVED
|
||||
}
|
||||
if (!worktree.hostId) {
|
||||
return resolved(
|
||||
getRuntimeEnvironmentIdForWorktree(state, worktree.id),
|
||||
getResolvedExecutionHostIdForWorktree(state, worktree.id)
|
||||
)
|
||||
// Why: a twin names no owner, and Open in must not launch it as this desktop's checkout.
|
||||
const owner = resolveOwnerWithLegacyFallback(state, { workspaceId: worktree.id })
|
||||
if (owner.kind === 'ambiguous') {
|
||||
return UNRESOLVED
|
||||
}
|
||||
// Why: an owner no row places was read as this desktop before the fold, and still is.
|
||||
if (owner.kind === 'missing') {
|
||||
return resolved(null)
|
||||
}
|
||||
const { endpoint, at } = owner.owner
|
||||
return resolved(endpoint.kind === 'environment' ? endpoint.environmentId : null, at)
|
||||
}
|
||||
// Why: an inactive row can name its host before the catalog has it, so the explicit host wins.
|
||||
const resolution = resolveStrictWorktreeOperationRouteResultForHost(
|
||||
|
||||
@@ -288,3 +288,17 @@ export function resolveOwnerWithLegacyFallback(
|
||||
}
|
||||
return match.kind === 'resolved' ? match : { kind: 'resolved', owner: SELF_LOCAL_AUTHORITY }
|
||||
}
|
||||
|
||||
/**
|
||||
* The paired server behind {@link resolveOwnerWithLegacyFallback}, or `null` for this app, a
|
||||
* directly dialed SSH target or a twin: for readers whose twin answer is "no server", as before.
|
||||
*/
|
||||
export function runtimeEnvironmentIdWithLegacyFallbackUnlessTwin(
|
||||
state: WorktreeRuntimeOwnerState,
|
||||
workspaceId: string
|
||||
): string | null {
|
||||
const match = resolveOwnerWithLegacyFallback(state, { workspaceId })
|
||||
return match.kind === 'resolved' && match.owner.endpoint.kind === 'environment'
|
||||
? match.owner.endpoint.environmentId
|
||||
: null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user