From 871a9c49b368fcd0edacbf100ffa67a1b180dd69 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sat, 30 May 2026 05:15:27 -0700 Subject: [PATCH] fix: append large workspace history safely --- .../worktree-ownership-large-history.test.ts | 25 +++++++++++++++++++ src/shared/worktree-ownership.ts | 15 +++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/shared/worktree-ownership-large-history.test.ts diff --git a/src/shared/worktree-ownership-large-history.test.ts b/src/shared/worktree-ownership-large-history.test.ts new file mode 100644 index 00000000000..36fb5df60e2 --- /dev/null +++ b/src/shared/worktree-ownership-large-history.test.ts @@ -0,0 +1,25 @@ +import { describe, expect, it } from 'vitest' +import type { GlobalSettings, Repo } from './types' +import { buildKnownOrcaWorkspaceLayouts } from './worktree-ownership' + +describe('buildKnownOrcaWorkspaceLayouts', () => { + it('handles workspace directory history larger than the JavaScript argument limit', () => { + const workspaceDirHistory = Array.from({ length: 130_000 }, (_, index) => ({ + path: `/old/workspaces/${index}`, + nestWorkspaces: index % 2 === 0 + })) + const settings = { + workspaceDir: '/orca/workspaces', + nestWorkspaces: true, + workspaceDirHistory + } satisfies Pick + const repo = { + path: '/repos/app' + } satisfies Pick + + const layouts = buildKnownOrcaWorkspaceLayouts(settings, repo) + + expect(layouts).toHaveLength(workspaceDirHistory.length + 1) + expect(layouts.at(-1)).toEqual({ path: '/old/workspaces/129999', nestWorkspaces: false }) + }) +}) diff --git a/src/shared/worktree-ownership.ts b/src/shared/worktree-ownership.ts index c628ed14202..a2a1d2eb52a 100644 --- a/src/shared/worktree-ownership.ts +++ b/src/shared/worktree-ownership.ts @@ -49,11 +49,11 @@ export function buildKnownOrcaWorkspaceLayouts( const layouts: OrcaWorkspaceLayout[] = [] if (!repo?.connectionId && settings.workspaceDir) { layouts.push({ path: settings.workspaceDir, nestWorkspaces: settings.nestWorkspaces }) - layouts.push(...(settings.workspaceDirHistory ?? [])) + appendWorkspaceLayouts(layouts, settings.workspaceDirHistory ?? []) } const wslLayouts = repo ? buildWslWorkspaceLayouts(repo.path, settings) : [] - layouts.push(...wslLayouts) + appendWorkspaceLayouts(layouts, wslLayouts) const seen = new Set() return layouts.filter((layout) => { @@ -66,6 +66,17 @@ export function buildKnownOrcaWorkspaceLayouts( }) } +function appendWorkspaceLayouts( + target: OrcaWorkspaceLayout[], + source: readonly OrcaWorkspaceLayout[] +): void { + // Why: persisted workspace history is unbounded; using push(...source) can + // exceed V8's argument limit before ownership classification can recover. + for (const layout of source) { + target.push(layout) + } +} + function buildWslWorkspaceLayouts( repoPath: string, settings: Pick