mirror of
https://github.com/stablyai/orca.git
synced 2026-11-04 02:57:36 +00:00
fix(wsl-mover): only the selected projects' session rows can refuse a WSL move
The session eligibility check treated host local's whole partition as the move's, as the SSH conversion does. So an agent session or unsaved draft in any other project on this desktop, or in a project an earlier move retained, refused every later WSL move from that distro. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+6
-3
@@ -8,6 +8,7 @@ import type {
|
||||
import {
|
||||
orcadMigrationOwnerMatchesScope,
|
||||
orcadMigrationOwnsRepoId,
|
||||
orcadMigrationScopeOwnsWholeHost,
|
||||
unqualifyOrcadMigrationOwnerKey,
|
||||
type OrcadMigrationSourceScope
|
||||
} from './orcad-source-scope'
|
||||
@@ -29,11 +30,13 @@ export function collectUnsupportedSessionItems(
|
||||
sourceTerminalTabIds: ReadonlySet<string>
|
||||
): string[] {
|
||||
const owns = (ownerKey: string): boolean => orcadMigrationOwnerMatchesScope(ownerKey, scope)
|
||||
const matches = (ownerKey: string): boolean =>
|
||||
Boolean(ownerKey) && (sourceHostPartition || owns(ownerKey))
|
||||
// A WSL move takes some of host `local`'s projects; the others, and rows a past move retained,
|
||||
// stay on this desktop untouched, so only the selected projects' rows can refuse it.
|
||||
const wholeHost = sourceHostPartition && orcadMigrationScopeOwnsWholeHost(scope)
|
||||
const matches = (ownerKey: string): boolean => Boolean(ownerKey) && (wholeHost || owns(ownerKey))
|
||||
const items: string[] = []
|
||||
// Another project's rows in this host's copy stay behind; only an unsaved draft there is work.
|
||||
if (sourceHostPartition) {
|
||||
if (wholeHost) {
|
||||
for (const [ownerKey, files] of Object.entries(session.openFilesByWorktree ?? {})) {
|
||||
if (!owns(ownerKey)) {
|
||||
items.push(...unsavedDraftItems(files, ownerKey))
|
||||
|
||||
@@ -234,6 +234,58 @@ describe('exportWslMoveManifest', () => {
|
||||
expect(exportWslMoveManifest(storeFor(state), REQUEST).blockers.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it("is not refused by another project's agent session or unsaved draft", () => {
|
||||
// On awin, any agent or draft anywhere on this desktop refused every WSL move (D1b-10 run).
|
||||
const state = sourceState()
|
||||
const elsewhere: SleepingAgentSessionRecord = {
|
||||
paneKey: 'windows-shell:missing-leaf',
|
||||
tabId: 'windows-shell',
|
||||
worktreeId: OTHER_WORKTREE,
|
||||
agent: 'codex',
|
||||
providerSession: { key: 'session_id', id: 'session-2' },
|
||||
prompt: 'Saved prompt',
|
||||
state: 'done',
|
||||
capturedAt: 1,
|
||||
updatedAt: 1,
|
||||
connectionId: null,
|
||||
origin: 'quit'
|
||||
}
|
||||
state.workspaceSession.sleepingAgentSessionsByPaneKey = { [elsewhere.paneKey]: elsewhere }
|
||||
state.workspaceSession.openFilesByWorktree = {
|
||||
[OTHER_WORKTREE]: [
|
||||
{
|
||||
filePath: 'C:\\code\\win\\notes.md',
|
||||
relativePath: 'notes.md',
|
||||
worktreeId: OTHER_WORKTREE,
|
||||
language: 'markdown',
|
||||
dirtyDraftContent: 'unsaved'
|
||||
}
|
||||
]
|
||||
}
|
||||
expect(exportWslMoveManifest(storeFor(state), REQUEST).blockers).toEqual([])
|
||||
})
|
||||
|
||||
it("is not refused by a project an earlier move retained, whose agent stays here", () => {
|
||||
const state = sourceState()
|
||||
const retainedWorktree = 'old::\\\\wsl.localhost\\Ubuntu\\home\\me\\old'
|
||||
state.repos.push(repo('old', '\\\\wsl.localhost\\Ubuntu\\home\\me\\old'))
|
||||
const record: SleepingAgentSessionRecord = {
|
||||
paneKey: 'old-shell:missing-leaf',
|
||||
tabId: 'old-shell',
|
||||
worktreeId: retainedWorktree,
|
||||
agent: 'claude',
|
||||
providerSession: { key: 'session_id', id: 'session-3' },
|
||||
prompt: 'Saved prompt',
|
||||
state: 'done',
|
||||
capturedAt: 1,
|
||||
updatedAt: 1,
|
||||
connectionId: null,
|
||||
origin: 'quit'
|
||||
}
|
||||
state.workspaceSession.sleepingAgentSessionsByPaneKey = { [record.paneKey]: record }
|
||||
expect(exportWslMoveManifest(storeFor(state), REQUEST).blockers).toEqual([])
|
||||
})
|
||||
|
||||
it('refuses to sign a scope naming a project that is no longer here', () => {
|
||||
expect(() =>
|
||||
exportWslMoveManifest(storeFor(sourceState()), { ...REQUEST, repoIds: ['app', 'gone'] })
|
||||
|
||||
Reference in New Issue
Block a user