mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
refactor: group local filesystem guards and search owners (#33624)
* refactor: group local filesystem guards and search owners * refactor: use process-host handle contract for listing cleanup * test: preserve concrete WSL module exports in search fixtures * test: remove unnecessary WSL owner mocks from search fixtures
This commit is contained in:
@@ -267,7 +267,7 @@
|
||||
1 test-no-real-time-wait:src/main/gitlab/work-item-details.test.ts
|
||||
1 test-no-real-time-wait:src/main/grok/grok-hook-stdin-no-eof.test.ts
|
||||
1 test-no-real-time-wait:src/main/ipc/created-worktree-reconciliation.test.ts
|
||||
1 test-no-real-time-wait:src/main/ipc/filesystem-auth.test.ts
|
||||
1 test-no-real-time-wait:src/main/ipc/filesystem/filesystem-auth.test.ts
|
||||
1 test-no-real-time-wait:src/main/ipc/filesystem/filesystem-content-search-cancellation.test.ts
|
||||
5 test-no-real-time-wait:src/main/ipc/filesystem/local-disk-write-precondition.test.ts
|
||||
2 test-no-real-time-wait:src/main/ipc/folder-repo-git-upgrade.test.ts
|
||||
|
||||
@@ -54,7 +54,6 @@ src/main/git/wsl-git-read-environment.ts
|
||||
src/main/github/gh-utils.ts
|
||||
src/main/hooks.ts
|
||||
src/main/ipc/developer-permissions.ts
|
||||
src/main/ipc/filesystem-list-files.ts
|
||||
src/main/ipc/filesystem/filesystem-handler-context.ts
|
||||
src/main/ipc/filesystem/watcher-process/parcel-watcher-cancellation-restart.ts
|
||||
src/main/ipc/filesystem/watcher-process/parcel-watcher-cancellation-tracker.ts
|
||||
|
||||
@@ -20053,11 +20053,11 @@
|
||||
"invariant": "Quick Open queries execute on the worktree host, find exact ignored-path matches beyond the legacy inventory prefix, return deterministic bounded results, and keep the paired runtime usable without overflowing its outbound reply buffer.",
|
||||
"oracle": "Create 88,763 paths with 77,792 ignored entries and a nominal 22 GiB sparse file, query exact late gitignored and .orcaignored targets through headed and headless paired runtimes, and require one deterministic match, a payload below 4 KiB, and a healthy follow-up worktree call.",
|
||||
"commands": [
|
||||
"pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/filesystem-search-file-paths.test.ts src/main/runtime/orca-runtime-files-search.test.ts src/main/runtime/rpc/methods/files-path-search.test.ts src/renderer/src/components/quick-open-file-list.react.test.tsx src/renderer/src/runtime/runtime-file-client-search-listing.test.ts src/shared/quick-open-transport-budget.test.ts --reporter=dot",
|
||||
"pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/filesystem/filesystem-search-file-paths.test.ts src/main/runtime/orca-runtime-files-search.test.ts src/main/runtime/rpc/methods/files-path-search.test.ts src/renderer/src/components/quick-open-file-list.react.test.tsx src/renderer/src/runtime/runtime-file-client-search-listing.test.ts src/shared/quick-open-transport-budget.test.ts --reporter=dot",
|
||||
"pnpm exec playwright test tests/e2e/paired-quick-open-large-tree.spec.ts --config tests/playwright.config.ts --workers=1"
|
||||
],
|
||||
"testFiles": [
|
||||
"src/main/ipc/filesystem-search-file-paths.test.ts",
|
||||
"src/main/ipc/filesystem/filesystem-search-file-paths.test.ts",
|
||||
"src/main/runtime/orca-runtime-files-search.test.ts",
|
||||
"src/main/runtime/rpc/methods/files-path-search.test.ts",
|
||||
"src/renderer/src/components/quick-open-file-list.react.test.tsx",
|
||||
@@ -20067,7 +20067,7 @@
|
||||
],
|
||||
"assertionRefs": [
|
||||
{
|
||||
"file": "src/main/ipc/filesystem-search-file-paths.test.ts",
|
||||
"file": "src/main/ipc/filesystem/filesystem-search-file-paths.test.ts",
|
||||
"assertions": [
|
||||
"host search stays bounded and respects gitignore plus .orcaignore traversal"
|
||||
]
|
||||
@@ -20087,7 +20087,7 @@
|
||||
"runner": "local",
|
||||
"platform": "macos",
|
||||
"result": "passed",
|
||||
"command": "pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/filesystem-search-file-paths.test.ts src/main/runtime/orca-runtime-files-search.test.ts src/main/runtime/rpc/methods/files-path-search.test.ts src/renderer/src/components/quick-open-file-list.react.test.tsx src/renderer/src/runtime/runtime-file-client-search-listing.test.ts src/shared/quick-open-transport-budget.test.ts --reporter=dot",
|
||||
"command": "pnpm exec vitest run --config config/vitest.config.ts src/main/ipc/filesystem/filesystem-search-file-paths.test.ts src/main/runtime/orca-runtime-files-search.test.ts src/main/runtime/rpc/methods/files-path-search.test.ts src/renderer/src/components/quick-open-file-list.react.test.tsx src/renderer/src/runtime/runtime-file-client-search-listing.test.ts src/shared/quick-open-transport-budget.test.ts --reporter=dot",
|
||||
"durationSeconds": 5,
|
||||
"summary": "Six focused files passed 52 tests across host search, runtime RPC, renderer query ownership, and transport bounds; existing React act warnings remained non-fatal."
|
||||
}
|
||||
|
||||
@@ -2538,8 +2538,8 @@
|
||||
"src/main/ipc/feedback-image-attachments.test.ts": 52,
|
||||
"src/main/ipc/feedback-request-ownership.test.ts": 56,
|
||||
"src/main/ipc/feedback.test.ts": 142,
|
||||
"src/main/ipc/filesystem-allowed-roots.test.ts": 730,
|
||||
"src/main/ipc/filesystem-auth.test.ts": 599,
|
||||
"src/main/ipc/filesystem/filesystem-allowed-roots.test.ts": 730,
|
||||
"src/main/ipc/filesystem/filesystem-auth.test.ts": 599,
|
||||
"src/main/ipc/filesystem/filesystem-branch-compare-diff.test.ts": 1385,
|
||||
"src/main/ipc/filesystem/filesystem-canonical-owner.test.ts": 340,
|
||||
"src/main/ipc/filesystem/filesystem-commit-message-generation.test.ts": 1421,
|
||||
@@ -2551,22 +2551,22 @@
|
||||
"src/main/ipc/filesystem/filesystem-download-transfers.test.ts": 1450,
|
||||
"src/main/ipc/filesystem/filesystem-git-commit-dispatch.test.ts": 1454,
|
||||
"src/main/ipc/filesystem/filesystem-git-status-staging.test.ts": 1645,
|
||||
"src/main/ipc/filesystem-import-local-rollback.test.ts": 86,
|
||||
"src/main/ipc/filesystem-import.test.ts": 1213,
|
||||
"src/main/ipc/filesystem-list-files-handler-name-filter.test.ts": 1554,
|
||||
"src/main/ipc/filesystem-list-files-name-filter.test.ts": 564,
|
||||
"src/main/ipc/filesystem-list-files.test.ts": 742,
|
||||
"src/main/ipc/filesystem/filesystem-import-local-rollback.test.ts": 86,
|
||||
"src/main/ipc/filesystem/filesystem-import.test.ts": 1213,
|
||||
"src/main/ipc/filesystem/filesystem-list-files-handler-name-filter.test.ts": 1554,
|
||||
"src/main/ipc/filesystem/filesystem-list-files-name-filter.test.ts": 564,
|
||||
"src/main/ipc/filesystem/filesystem-list-files.test.ts": 742,
|
||||
"src/main/ipc/filesystem/filesystem-markdown-document-listing.test.ts": 1217,
|
||||
"src/main/ipc/filesystem/filesystem-mutations-runtime-upload.test.ts": 605,
|
||||
"src/main/ipc/filesystem/filesystem-mutations.test.ts": 1536,
|
||||
"src/main/ipc/filesystem-path-containment-remote-enoent.test.ts": 40,
|
||||
"src/main/ipc/filesystem-path-containment-unicode-normalization.test.ts": 616,
|
||||
"src/main/ipc/filesystem/filesystem-path-containment-remote-enoent.test.ts": 40,
|
||||
"src/main/ipc/filesystem/filesystem-path-containment-unicode-normalization.test.ts": 616,
|
||||
"src/main/ipc/filesystem/filesystem-pull-request-linked-issue-lifetime.test.ts": 2341,
|
||||
"src/main/ipc/filesystem/filesystem-quick-open-options.integration.test.ts": 1280,
|
||||
"src/main/ipc/filesystem-runtime-upload-staging.test.ts": 62,
|
||||
"src/main/ipc/filesystem-search-file-paths.test.ts": 361,
|
||||
"src/main/ipc/filesystem-search-rg-timeout.test.ts": 1957,
|
||||
"src/main/ipc/filesystem-symlink-directory-entries.test.ts": 33,
|
||||
"src/main/ipc/filesystem/filesystem-runtime-upload-staging.test.ts": 62,
|
||||
"src/main/ipc/filesystem/filesystem-search-file-paths.test.ts": 361,
|
||||
"src/main/ipc/filesystem/filesystem-search-rg-timeout.test.ts": 1957,
|
||||
"src/main/ipc/filesystem/filesystem-symlink-directory-entries.test.ts": 33,
|
||||
"src/main/ipc/filesystem-watcher-canonical-root-paths.test.ts": 456,
|
||||
"src/main/ipc/filesystem/watchers/filesystem-watcher-document-lifetime.test.ts": 388,
|
||||
"src/main/ipc/filesystem/watchers/filesystem-watcher-event-batch.test.ts": 34,
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
type ValidateAiVaultSessionDeleteTargetArgs
|
||||
} from './session-delete-target'
|
||||
import { tryDeleteWslUncPath, WslDeleteValidationError } from '../wsl-unc-delete'
|
||||
import { isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
|
||||
// Remove companions first so partial failure leaves the transcript visible for retry.
|
||||
export async function deleteAiVaultSessionFile(
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
isRuntimeEnvironmentManuallyDisconnected,
|
||||
RUNTIME_MANUALLY_DISCONNECTED_MESSAGE
|
||||
} from './runtime-environments/runtime-environment-manual-disconnect'
|
||||
import { stageOneSourceForRuntimeUpload } from './filesystem-runtime-upload-staging'
|
||||
import { stageOneSourceForRuntimeUpload } from './filesystem/filesystem-runtime-upload-staging'
|
||||
import { streamExternalFileSlices } from './runtime-upload-file-stream'
|
||||
import { formatByteCeiling } from './runtime-import-limits'
|
||||
|
||||
|
||||
+23
-20
@@ -2,30 +2,33 @@ import { mkdir, mkdtemp, realpath, rm, symlink, writeFile } from 'node:fs/promis
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, resolve } from 'node:path'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { Store } from '../persistence'
|
||||
import type * as RepoWorktrees from '../repo-worktrees'
|
||||
import { listRepoWorktreeGraph } from '../repo-worktrees'
|
||||
import type * as ProjectGroupsModule from '../../shared/project-groups'
|
||||
import { buildProjectGroupChildIndex, getProjectGroupSubtreeIds } from '../../shared/project-groups'
|
||||
import { isPathInsideOrEqual } from '../../shared/cross-platform-path'
|
||||
import type * as CrossPlatformPathModule from '../../shared/cross-platform-path'
|
||||
import { getWorktreeMirrorDistro } from '../project-runtime-git-options'
|
||||
import type { FolderWorkspace } from '../../shared/folder-workspace-types'
|
||||
import type { ProjectGroup } from '../../shared/project-group-types'
|
||||
import type { Project } from '../../shared/project-types'
|
||||
import type { Repo } from '../../shared/repo-types'
|
||||
import type { Store } from '../../persistence/loading-store/store'
|
||||
import type * as RepoWorktrees from '../../repo-worktrees'
|
||||
import { listRepoWorktreeGraph } from '../../repo-worktrees'
|
||||
import type * as ProjectGroupsModule from '../../../shared/project-groups'
|
||||
import {
|
||||
buildProjectGroupChildIndex,
|
||||
getProjectGroupSubtreeIds
|
||||
} from '../../../shared/project-groups'
|
||||
import { isPathInsideOrEqual } from '../../../shared/cross-platform-path'
|
||||
import type * as CrossPlatformPathModule from '../../../shared/cross-platform-path'
|
||||
import { getWorktreeMirrorDistro } from '../../project-runtime-git-options'
|
||||
import type { FolderWorkspace } from '../../../shared/folder-workspace-types'
|
||||
import type { ProjectGroup } from '../../../shared/project-group-types'
|
||||
import type { Project } from '../../../shared/project-types'
|
||||
import type { Repo } from '../../../shared/repo-types'
|
||||
import { getAllowedRoots } from './filesystem-allowed-roots'
|
||||
import { resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { invalidateAuthorizedRootsCache } from './registered-worktree-roots-cache'
|
||||
import { computeWorkspaceRoot, getWorktreePathSettings } from './worktree-logic'
|
||||
import { invalidateAuthorizedRootsCache } from '../registered-worktree-roots-cache'
|
||||
import { computeWorkspaceRoot, getWorktreePathSettings } from '../worktree-logic'
|
||||
|
||||
vi.mock('../repo-worktrees', async () => {
|
||||
const actual = await vi.importActual<typeof RepoWorktrees>('../repo-worktrees')
|
||||
vi.mock('../../repo-worktrees', async () => {
|
||||
const actual = await vi.importActual<typeof RepoWorktrees>('../../repo-worktrees')
|
||||
return { ...actual, listRepoWorktreeGraph: vi.fn(async () => []) }
|
||||
})
|
||||
|
||||
vi.mock('../../shared/project-groups', async () => {
|
||||
const actual = await vi.importActual<typeof ProjectGroupsModule>('../../shared/project-groups')
|
||||
vi.mock('../../../shared/project-groups', async () => {
|
||||
const actual = await vi.importActual<typeof ProjectGroupsModule>('../../../shared/project-groups')
|
||||
return {
|
||||
...actual,
|
||||
buildProjectGroupChildIndex: vi.fn(actual.buildProjectGroupChildIndex),
|
||||
@@ -33,9 +36,9 @@ vi.mock('../../shared/project-groups', async () => {
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('../../shared/cross-platform-path', async () => {
|
||||
vi.mock('../../../shared/cross-platform-path', async () => {
|
||||
const actual = await vi.importActual<typeof CrossPlatformPathModule>(
|
||||
'../../shared/cross-platform-path'
|
||||
'../../../shared/cross-platform-path'
|
||||
)
|
||||
return { ...actual, isPathInsideOrEqual: vi.fn(actual.isPathInsideOrEqual) }
|
||||
})
|
||||
+10
-12
@@ -1,20 +1,18 @@
|
||||
import { isAbsolute, resolve } from 'node:path'
|
||||
import type { RuntimeStore } from '../runtime/runtime-store-contract'
|
||||
import { computeWorkspaceRootWithin, getWorktreePathSettings } from './worktree-logic'
|
||||
import {
|
||||
getWorktreeMirrorDistroForRuntime,
|
||||
resolveLocalProjectRuntimesForRepos
|
||||
} from '../project-runtime-git-options'
|
||||
import { isPathInsideOrEqual } from '../../shared/cross-platform-path'
|
||||
import type { RuntimeStore } from '../../runtime/runtime-store-contract'
|
||||
import { computeWorkspaceRootWithin, getWorktreePathSettings } from '../worktree-logic'
|
||||
import { getWorktreeMirrorDistroForRuntime } from '../../project-runtime-git-options'
|
||||
import { resolveLocalProjectRuntimesForRepos } from '../../local-project-runtime-resolution'
|
||||
import { isPathInsideOrEqual } from '../../../shared/cross-platform-path'
|
||||
import {
|
||||
buildProjectGroupChildIndex,
|
||||
collectProjectGroupSubtreeIds,
|
||||
type ProjectGroupChildIndex
|
||||
} from '../../shared/project-groups'
|
||||
import type { FolderWorkspace } from '../../shared/folder-workspace-types'
|
||||
import type { ProjectGroup } from '../../shared/project-group-types'
|
||||
import type { Repo } from '../../shared/repo-types'
|
||||
import { hasRemoteFilesystemOwner } from './remote-filesystem-owner'
|
||||
} from '../../../shared/project-groups'
|
||||
import type { FolderWorkspace } from '../../../shared/folder-workspace-types'
|
||||
import type { ProjectGroup } from '../../../shared/project-group-types'
|
||||
import type { Repo } from '../../../shared/repo-types'
|
||||
import { hasRemoteFilesystemOwner } from '../remote-filesystem-owner'
|
||||
|
||||
type FolderScopeStore = Pick<RuntimeStore, 'getRepos'> &
|
||||
Partial<Pick<RuntimeStore, 'getProjectGroups' | 'getFolderWorkspaces'>>
|
||||
+12
-12
@@ -3,13 +3,13 @@ import { mkdir, mkdtemp, realpath, rm, symlink } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, resolve } from 'node:path'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { Store } from '../persistence'
|
||||
import type * as RepoWorktrees from '../repo-worktrees'
|
||||
import { listRepoWorktreeGraph } from '../repo-worktrees'
|
||||
import type { FolderWorkspace } from '../../shared/folder-workspace-types'
|
||||
import type { ProjectGroup } from '../../shared/project-group-types'
|
||||
import type { Repo } from '../../shared/repo-types'
|
||||
import type { GitWorktreeInfo } from '../../shared/worktree/types'
|
||||
import type { Store } from '../../persistence/loading-store/store'
|
||||
import type * as RepoWorktrees from '../../repo-worktrees'
|
||||
import { listRepoWorktreeGraph } from '../../repo-worktrees'
|
||||
import type { FolderWorkspace } from '../../../shared/folder-workspace-types'
|
||||
import type { ProjectGroup } from '../../../shared/project-group-types'
|
||||
import type { Repo } from '../../../shared/repo-types'
|
||||
import type { GitWorktreeInfo } from '../../../shared/worktree/types'
|
||||
import { resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { isDescendantOrEqual, validateGitRelativeFilePath } from './filesystem-path-containment'
|
||||
import {
|
||||
@@ -18,10 +18,10 @@ import {
|
||||
rebuildAuthorizedRootsCache,
|
||||
registerCreatedWorktreeRoot,
|
||||
resolveRegisteredWorktreePath
|
||||
} from './registered-worktree-roots-cache'
|
||||
} from '../registered-worktree-roots-cache'
|
||||
|
||||
vi.mock('../repo-worktrees', async () => {
|
||||
const actual = await vi.importActual<typeof RepoWorktrees>('../repo-worktrees')
|
||||
vi.mock('../../repo-worktrees', async () => {
|
||||
const actual = await vi.importActual<typeof RepoWorktrees>('../../repo-worktrees')
|
||||
return {
|
||||
...actual,
|
||||
listRepoWorktreeGraph: vi.fn()
|
||||
@@ -390,7 +390,7 @@ describe('filesystem-auth path containment', () => {
|
||||
|
||||
it('accepts Windows descendants when drive and root casing differ', async () => {
|
||||
vi.resetModules()
|
||||
vi.doMock('../repo-worktrees', () => ({
|
||||
vi.doMock('../../repo-worktrees', () => ({
|
||||
isRepoRoot: vi.fn(),
|
||||
listRepoWorktreeGraph: vi.fn()
|
||||
}))
|
||||
@@ -414,7 +414,7 @@ describe('filesystem-auth path containment', () => {
|
||||
).toBe(false)
|
||||
} finally {
|
||||
vi.doUnmock('path')
|
||||
vi.doUnmock('../repo-worktrees')
|
||||
vi.doUnmock('../../repo-worktrees')
|
||||
vi.resetModules()
|
||||
}
|
||||
})
|
||||
@@ -1,14 +1,14 @@
|
||||
import { resolve, dirname, basename } from 'node:path'
|
||||
import type { RuntimeStore } from '../runtime/runtime-store-contract'
|
||||
import type { RuntimeStore } from '../../runtime/runtime-store-contract'
|
||||
import { lstat, realpath } from 'node:fs/promises'
|
||||
import { PATH_OUTSIDE_ALLOWED_DIRECTORIES } from '../../shared/local-file-access'
|
||||
import { PATH_OUTSIDE_ALLOWED_DIRECTORIES } from '../../../shared/local-file-access'
|
||||
import { getAllowedRoots } from './filesystem-allowed-roots'
|
||||
import { isDescendantOrEqual, isENOENT, normalizeExistingPath } from './filesystem-path-containment'
|
||||
import {
|
||||
ensureAuthorizedRootsCache,
|
||||
isPathAllowedByCanonicalRegisteredRoot,
|
||||
isRegisteredWorktreePath
|
||||
} from './registered-worktree-roots-cache'
|
||||
} from '../registered-worktree-roots-cache'
|
||||
|
||||
export const PATH_ACCESS_DENIED_MESSAGE = `${PATH_OUTSIDE_ALLOWED_DIRECTORIES}. If this blocks a legitimate workflow, please file a GitHub issue.`
|
||||
/** Lazily share allowed roots across every check in one authorization. */
|
||||
@@ -9,8 +9,8 @@ import {
|
||||
getAllowedRoots,
|
||||
getLocalRepos,
|
||||
resolveUnanchoredWorkspaceRoot
|
||||
} from '../filesystem-allowed-roots'
|
||||
import { isPathAllowed } from '../filesystem-auth'
|
||||
} from './filesystem-allowed-roots'
|
||||
import { isPathAllowed } from './filesystem-auth'
|
||||
import {
|
||||
__resetCreatedWorktreeRootsForTests,
|
||||
invalidateAuthorizedRootsCache,
|
||||
@@ -35,7 +35,9 @@ vi.mock('../worktree-logic', () => ({
|
||||
getWorktreePathSettings: mocks.pathSettings
|
||||
}))
|
||||
vi.mock('../../project-runtime-git-options', () => ({
|
||||
getWorktreeMirrorDistroForRuntime: vi.fn(),
|
||||
getWorktreeMirrorDistroForRuntime: vi.fn()
|
||||
}))
|
||||
vi.mock('../../local-project-runtime-resolution', () => ({
|
||||
resolveLocalProjectRuntimesForRepos: mocks.projectRuntimes
|
||||
}))
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ vi.mock('../../wsl', () => ({
|
||||
toWindowsWslPath: toWindowsWslPathMock
|
||||
}))
|
||||
|
||||
vi.mock('../filesystem-auth', () => ({
|
||||
vi.mock('./filesystem-auth', () => ({
|
||||
authorizeExternalPath: vi.fn(async (value: string) => value),
|
||||
resolveAuthorizedPath: resolveAuthorizedPathMock
|
||||
}))
|
||||
@@ -53,7 +53,7 @@ vi.mock('../local-file-access-resolution', () => ({
|
||||
resolveLocalFileRequestPath: resolveAuthorizedPathMock
|
||||
}))
|
||||
|
||||
vi.mock('../filesystem-path-containment', () => ({
|
||||
vi.mock('./filesystem-path-containment', () => ({
|
||||
isENOENT: vi.fn(() => false),
|
||||
validateGitRelativeFilePath: vi.fn((value: string) => value)
|
||||
}))
|
||||
@@ -62,7 +62,7 @@ vi.mock('../registered-worktree-roots-cache', () => ({
|
||||
resolveRegisteredWorktreePath: vi.fn(async (value: string) => value)
|
||||
}))
|
||||
|
||||
vi.mock('../filesystem-list-files', () => ({
|
||||
vi.mock('./filesystem-list-files', () => ({
|
||||
listQuickOpenFiles: vi.fn()
|
||||
}))
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { rename, rm, stat } from 'node:fs/promises'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { isENOENT } from '../filesystem-path-containment'
|
||||
import { isENOENT } from './filesystem-path-containment'
|
||||
|
||||
export function decodeDownloadedFileContent(content: string, encoding: 'utf8' | 'base64'): Buffer {
|
||||
return encoding === 'base64' ? Buffer.from(content, 'base64') : Buffer.from(content, 'utf8')
|
||||
|
||||
@@ -3,10 +3,7 @@ import type { GitDiffResult } from '../../../shared/git-diff-compare-types'
|
||||
import { getBranchDiff, getCommitDiff } from '../../git/status'
|
||||
import { resolveRegisteredWorktreePath } from '../registered-worktree-roots-cache'
|
||||
import { getLocalGitOptionsForRegisteredWorktree } from '../local-worktree-runtime-options'
|
||||
import {
|
||||
validateFullGitObjectId,
|
||||
validateGitRelativeFilePath
|
||||
} from '../filesystem-path-containment'
|
||||
import { validateFullGitObjectId, validateGitRelativeFilePath } from './filesystem-path-containment'
|
||||
import type { FilesystemHandlerContext } from './filesystem-handler-context'
|
||||
import { requireReachableGitRoute } from '../../providers/execution-host-provider-dispatch'
|
||||
import { getConnectionExecutionHostId } from '../../../shared/execution-host'
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
getLocalRepoForRegisteredWorktree
|
||||
} from '../local-worktree-runtime-options'
|
||||
import { getWorktreeSharedLinkPaths } from '../../git/worktree-shared-directories'
|
||||
import { validateGitRelativeFilePath } from '../filesystem-path-containment'
|
||||
import { validateGitRelativeFilePath } from './filesystem-path-containment'
|
||||
import type { FilesystemHandlerContext } from './filesystem-handler-context'
|
||||
import { parseGitStageWorktreeScope } from '../../../shared/git-stage-worktree-scope'
|
||||
import { requireReachableGitRoute } from '../../providers/execution-host-provider-dispatch'
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
findKnownHugeFolderPathsToIgnore
|
||||
} from '../../git/huge-folder-ignore'
|
||||
import { resolveRegisteredWorktreePath } from '../registered-worktree-roots-cache'
|
||||
import { validateGitRelativeFilePath } from '../filesystem-path-containment'
|
||||
import { validateGitRelativeFilePath } from './filesystem-path-containment'
|
||||
import {
|
||||
getLocalGitOptionsForRegisteredWorktree,
|
||||
getLocalGitOptionsForRepo,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ipcMain } from 'electron'
|
||||
import { awaitWindowsHostGitEnvironmentReady } from '../../git/runner'
|
||||
import { getRemoteCommitUrl, getRemoteFileUrl } from '../../git/repo'
|
||||
import { resolveRegisteredWorktreePath } from '../registered-worktree-roots-cache'
|
||||
import { validateFullGitObjectId } from '../filesystem-path-containment'
|
||||
import { validateFullGitObjectId } from './filesystem-path-containment'
|
||||
import type { FilesystemHandlerContext } from './filesystem-handler-context'
|
||||
import { requireReachableGitRoute } from '../../providers/execution-host-provider-dispatch'
|
||||
import { getConnectionExecutionHostId } from '../../../shared/execution-host'
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ import { lstat } from 'node:fs/promises'
|
||||
import { basename, join, resolve } from 'node:path'
|
||||
import { isENOENT } from './filesystem-path-containment'
|
||||
import { classifyImportSource } from './filesystem-import-source-stat'
|
||||
import { deconflictCopyName } from '../../shared/import-copy-name'
|
||||
import type { ImportItemResult } from '../../shared/filesystem-import-result-types'
|
||||
import { deconflictCopyName } from '../../../shared/import-copy-name'
|
||||
import type { ImportItemResult } from '../../../shared/filesystem-import-result-types'
|
||||
import {
|
||||
copyLocalFileNoFollow,
|
||||
preScanForSymlinks,
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import type { Stats } from 'node:fs'
|
||||
import { lstat } from 'node:fs/promises'
|
||||
import type { ImportSkipReason } from '../../shared/filesystem-import-result-types'
|
||||
import { errorMessage } from '../../shared/error-message'
|
||||
import { isPermissionError } from '../win32-utils'
|
||||
import type { ImportSkipReason } from '../../../shared/filesystem-import-result-types'
|
||||
import { errorMessage } from '../../../shared/error-message'
|
||||
import { isPermissionError } from '../../win32-utils'
|
||||
import { isENOENT } from './filesystem-path-containment'
|
||||
|
||||
export type ImportSourceRejection =
|
||||
+1
-1
@@ -47,7 +47,7 @@ vi.mock('fs/promises', () => ({
|
||||
unlink: unlinkMock
|
||||
}))
|
||||
|
||||
import { registerFilesystemMutationHandlers } from './filesystem/filesystem-mutations'
|
||||
import { registerFilesystemMutationHandlers } from './filesystem-mutations'
|
||||
|
||||
const REPO_PATH = path.resolve('/workspace/repo')
|
||||
const WORKSPACE_DIR = path.resolve('/workspace')
|
||||
+22
-25
@@ -1,53 +1,50 @@
|
||||
import { EventEmitter } from 'node:events'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { handlers, store, resetFilesystemIpcMocks } from './filesystem/filesystem-test-harness'
|
||||
import { handlers, store, resetFilesystemIpcMocks } from './filesystem-test-harness'
|
||||
|
||||
const { listQuickOpenFilesMock } = vi.hoisted(() => ({ listQuickOpenFilesMock: vi.fn() }))
|
||||
|
||||
vi.mock('electron', async () => (await import('./filesystem/filesystem-test-harness')).electronMock)
|
||||
vi.mock('electron', async () => (await import('./filesystem-test-harness')).electronMock)
|
||||
vi.mock('fs/promises', async () => (await import('./filesystem-test-harness')).fsPromisesMock)
|
||||
vi.mock(
|
||||
'fs/promises',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).fsPromisesMock
|
||||
'../../wsl-unc-delete',
|
||||
async () => (await import('./filesystem-test-harness')).wslUncDeleteMock
|
||||
)
|
||||
vi.mock(
|
||||
'../wsl-unc-delete',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).wslUncDeleteMock
|
||||
'../../crash-reporting/crash-breadcrumb-store',
|
||||
async () => (await import('./filesystem-test-harness')).crashBreadcrumbMock
|
||||
)
|
||||
vi.mock(
|
||||
'../crash-reporting/crash-breadcrumb-store',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).crashBreadcrumbMock
|
||||
'../../git/status',
|
||||
async () => (await import('./filesystem-test-harness')).gitStatusModuleMock
|
||||
)
|
||||
vi.mock(
|
||||
'../git/status',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).gitStatusModuleMock
|
||||
'../../git/check-ignored-paths',
|
||||
async () => (await import('./filesystem-test-harness')).gitIgnoredPathsMock
|
||||
)
|
||||
vi.mock(
|
||||
'../git/check-ignored-paths',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).gitIgnoredPathsMock
|
||||
'../../git/worktree',
|
||||
async () => (await import('./filesystem-test-harness')).gitWorktreeMock
|
||||
)
|
||||
vi.mock(
|
||||
'../git/worktree',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).gitWorktreeMock
|
||||
'../../text-generation/commit-message-text-generation',
|
||||
async () => (await import('./filesystem-test-harness')).textGenerationModuleMock
|
||||
)
|
||||
vi.mock(
|
||||
'../text-generation/commit-message-text-generation',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).textGenerationModuleMock
|
||||
'../../text-generation/pull-request-context',
|
||||
async () => (await import('./filesystem-test-harness')).pullRequestContextMock
|
||||
)
|
||||
vi.mock(
|
||||
'../text-generation/pull-request-context',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).pullRequestContextMock
|
||||
'../../source-control/pull-request-template',
|
||||
async () => (await import('./filesystem-test-harness')).pullRequestTemplateMock
|
||||
)
|
||||
vi.mock(
|
||||
'../source-control/pull-request-template',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).pullRequestTemplateMock
|
||||
)
|
||||
vi.mock(
|
||||
'../source-control/pull-request-linked-issue',
|
||||
async () => (await import('./filesystem/filesystem-test-harness')).pullRequestLinkedIssueMock
|
||||
'../../source-control/pull-request-linked-issue',
|
||||
async () => (await import('./filesystem-test-harness')).pullRequestLinkedIssueMock
|
||||
)
|
||||
vi.mock('./filesystem-list-files', () => ({ listQuickOpenFiles: listQuickOpenFilesMock }))
|
||||
|
||||
import { registerFilesystemHandlers } from './filesystem/filesystem'
|
||||
import { registerFilesystemHandlers } from './filesystem'
|
||||
|
||||
function registerHandlers(): void {
|
||||
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: handlers under test only read repos and settings from the harness store.
|
||||
+4
-4
@@ -1,17 +1,17 @@
|
||||
import { EventEmitter } from 'node:events'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { Store } from '../persistence'
|
||||
import type * as GitRunner from '../git/runner'
|
||||
import type { Store } from '../../persistence/loading-store/store'
|
||||
import type * as GitRunner from '../../git/runner'
|
||||
import {
|
||||
pathMatchesFileNameFilterTokens,
|
||||
splitFileNameFilterTokens
|
||||
} from '../../shared/file-name-filter-tokens'
|
||||
} from '../../../shared/file-name-filter-tokens'
|
||||
|
||||
const { wslAwareSpawnMock } = vi.hoisted(() => ({
|
||||
wslAwareSpawnMock: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('../git/runner', async (importOriginal) => ({
|
||||
vi.mock('../../git/runner', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof GitRunner>()),
|
||||
wslAwareSpawn: wslAwareSpawnMock
|
||||
}))
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it, vi, beforeEach } from 'vitest'
|
||||
import type * as BundledRipgrepPath from '../ripgrep/bundled-ripgrep-path'
|
||||
import type * as BundledRipgrepPath from '../../ripgrep/bundled-ripgrep-path'
|
||||
|
||||
const {
|
||||
spawnMock,
|
||||
@@ -24,20 +24,20 @@ vi.mock('./filesystem-auth', () => ({
|
||||
resolveAuthorizedPath: resolveAuthorizedPathMock
|
||||
}))
|
||||
|
||||
vi.mock('../ripgrep/bundled-ripgrep-path', async (importOriginal) => ({
|
||||
vi.mock('../../ripgrep/bundled-ripgrep-path', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof BundledRipgrepPath>()),
|
||||
bundledRipgrepCommand: bundledRipgrepCommandMock
|
||||
}))
|
||||
|
||||
vi.mock('./local-worktree-runtime-options', () => ({
|
||||
vi.mock('../local-worktree-runtime-options', () => ({
|
||||
getLocalGitOptionsForRegisteredWorktree: getLocalGitOptionsForRegisteredWorktreeMock
|
||||
}))
|
||||
|
||||
import { listQuickOpenFiles } from './filesystem-list-files'
|
||||
import { EventEmitter } from 'node:events'
|
||||
import type { Store } from '../persistence'
|
||||
import type { Store } from '../../persistence/loading-store/store'
|
||||
import type { ChildProcess } from 'node:child_process'
|
||||
import { FileListingCancelledError } from '../../shared/file-listing-cancellation'
|
||||
import { FileListingCancelledError } from '../../../shared/file-listing-cancellation'
|
||||
|
||||
const BUNDLED_RG = '/bundled/rg'
|
||||
const BUNDLED_ERROR = "Orca's bundled search tool (ripgrep) could not start"
|
||||
+32
-36
@@ -1,25 +1,30 @@
|
||||
import { FileInventoryBudget, FileInventoryCapacityError } from '../../shared/file-inventory-budget'
|
||||
import { quickOpenListingPathFilter } from '../../shared/quick-open-listing-path-filter'
|
||||
import { getQuickOpenRgOutputMode } from '../../shared/quick-open-ripgrep-output-mode'
|
||||
import { RipgrepFilenameDecoder, RipgrepFilenameError } from '../../shared/ripgrep-filename-decoder'
|
||||
import {
|
||||
FileInventoryBudget,
|
||||
FileInventoryCapacityError
|
||||
} from '../../../shared/file-inventory-budget'
|
||||
import { quickOpenListingPathFilter } from '../../../shared/quick-open-listing-path-filter'
|
||||
import { getQuickOpenRgOutputMode } from '../../../shared/quick-open-ripgrep-output-mode'
|
||||
import {
|
||||
RipgrepFilenameDecoder,
|
||||
RipgrepFilenameError
|
||||
} from '../../../shared/ripgrep-filename-decoder'
|
||||
import { sep } from 'node:path'
|
||||
import type { ChildProcess } from 'node:child_process'
|
||||
import type { RuntimeStore as Store } from '../runtime/runtime-store-contract'
|
||||
import type { RuntimeStore as Store } from '../../runtime/runtime-store-contract'
|
||||
import { resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { toWindowsWslPath } from '../wsl'
|
||||
import { resolveBundledRipgrepWslRouting } from '../ripgrep/bundled-ripgrep-wsl-routing'
|
||||
import { getLocalGitOptionsForRegisteredWorktree } from './local-worktree-runtime-options'
|
||||
import { toWindowsWslPath } from '../../../shared/wsl-paths'
|
||||
import { resolveBundledRipgrepWslRouting } from '../../ripgrep/bundled-ripgrep-wsl-routing'
|
||||
import { getLocalGitOptionsForRegisteredWorktree } from '../local-worktree-runtime-options'
|
||||
import {
|
||||
buildExcludePathPrefixes,
|
||||
buildRgArgsForQuickOpen,
|
||||
normalizeQuickOpenRgLine
|
||||
} from '../../shared/quick-open-filter'
|
||||
} from '../../../shared/quick-open-filter'
|
||||
import {
|
||||
limitQuickOpenFilesBySerializedBytes,
|
||||
serializedQuickOpenPathBytes
|
||||
} from '../../shared/quick-open-transport-budget'
|
||||
import { bundledRipgrepUnavailableError } from '../ripgrep/bundled-ripgrep-path'
|
||||
import { spawnBundledRipgrep } from '../ripgrep/bundled-ripgrep-spawn'
|
||||
} from '../../../shared/quick-open-transport-budget'
|
||||
import { bundledRipgrepUnavailableError } from '../../ripgrep/bundled-ripgrep-path'
|
||||
import { spawnBundledRipgrep } from '../../ripgrep/bundled-ripgrep-spawn'
|
||||
import {
|
||||
absorbPendingRipgrepSpawnError,
|
||||
isRipgrepUnavailableExit,
|
||||
@@ -30,8 +35,12 @@ import {
|
||||
killSpawnedRipgrepProcess,
|
||||
ripgrepMissingCwdError,
|
||||
RipgrepUnavailableError
|
||||
} from '../../shared/ripgrep-process-availability'
|
||||
import { fileListingCancellationError } from '../../shared/file-listing-cancellation'
|
||||
} from '../../../shared/ripgrep-process-availability'
|
||||
import { fileListingCancellationError } from '../../../shared/file-listing-cancellation'
|
||||
import {
|
||||
finishFilesystemListingProcesses,
|
||||
type FilesystemListingProcess
|
||||
} from './filesystem-listing-process-cleanup'
|
||||
|
||||
export async function listQuickOpenFiles(
|
||||
rootPath: string,
|
||||
@@ -64,11 +73,7 @@ export async function listQuickOpenFiles(
|
||||
maxResults === undefined && maxSerializedBytes === undefined ? new FileInventoryBudget() : null
|
||||
const files = new Set<string>()
|
||||
let serializedBytes = 2
|
||||
const children: {
|
||||
child: ChildProcess
|
||||
isDone: () => boolean
|
||||
finish: (error?: Error) => void
|
||||
}[] = []
|
||||
const children: FilesystemListingProcess[] = []
|
||||
// WSL rg may emit absolute Linux paths; distro identity comes from UNC paths or project runtime.
|
||||
const { primary, ignoredPass } = buildRgArgsForQuickOpen({
|
||||
// Use a relative search root so root-relative exclusion globs prune traversal instead of only filtering output.
|
||||
@@ -125,7 +130,10 @@ export async function listQuickOpenFiles(
|
||||
} catch (error) {
|
||||
buf = ''
|
||||
files.clear()
|
||||
killSurvivors(error instanceof Error ? error : new FileInventoryCapacityError())
|
||||
finishFilesystemListingProcesses(
|
||||
children,
|
||||
error instanceof Error ? error : new FileInventoryCapacityError()
|
||||
)
|
||||
return true
|
||||
}
|
||||
files.add(relPath)
|
||||
@@ -157,7 +165,7 @@ export async function listQuickOpenFiles(
|
||||
while (delimiterIdx !== -1) {
|
||||
if (processLine(buf.substring(start, delimiterIdx))) {
|
||||
buf = ''
|
||||
killSurvivors()
|
||||
finishFilesystemListingProcesses(children)
|
||||
return
|
||||
}
|
||||
start = delimiterIdx + 1
|
||||
@@ -220,7 +228,7 @@ export async function listQuickOpenFiles(
|
||||
}
|
||||
if (buf && processLine(buf)) {
|
||||
buf = ''
|
||||
killSurvivors()
|
||||
finishFilesystemListingProcesses(children)
|
||||
return
|
||||
}
|
||||
if (code === 0 || code === 1 || (code === 2 && parseablePathCount > 0)) {
|
||||
@@ -277,18 +285,6 @@ export async function listQuickOpenFiles(
|
||||
}
|
||||
})
|
||||
|
||||
const killSurvivors = (error?: Error): void => {
|
||||
for (const entry of children) {
|
||||
if (entry.isDone()) {
|
||||
continue
|
||||
}
|
||||
entry.finish(error)
|
||||
if (entry.child.exitCode === null && entry.child.signalCode === null) {
|
||||
killSpawnedRipgrepProcess(entry.child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (options.includeIgnored === false) {
|
||||
await runRg(primary)
|
||||
@@ -320,7 +316,7 @@ export async function listQuickOpenFiles(
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
killSurvivors()
|
||||
finishFilesystemListingProcesses(children)
|
||||
throw err instanceof RipgrepUnavailableError ? bundledRipgrepUnavailableError() : err
|
||||
}
|
||||
const result = Array.from(files).slice(0, maxResults)
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { ChildProcessHandle } from '@orca/process-host/process-spec'
|
||||
import { killSpawnedRipgrepProcess } from '../../../shared/ripgrep-process-availability'
|
||||
|
||||
export type FilesystemListingProcess = {
|
||||
child: ChildProcessHandle
|
||||
isDone: () => boolean
|
||||
finish: (error?: Error) => void
|
||||
}
|
||||
|
||||
export function finishFilesystemListingProcesses(
|
||||
children: readonly FilesystemListingProcess[],
|
||||
error?: Error
|
||||
): void {
|
||||
for (const entry of children) {
|
||||
if (entry.isDone()) {
|
||||
continue
|
||||
}
|
||||
entry.finish(error)
|
||||
if (entry.child.exitCode === null && entry.child.signalCode === null) {
|
||||
killSpawnedRipgrepProcess(entry.child)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,17 +14,17 @@ import { resolveLocalDroppedPathsForAgent } from '../dropped-path-resolution'
|
||||
import type { SshMutationExpectation } from '../../../shared/ssh-types'
|
||||
import { assertSshMutationExpectation } from '../../ssh/connection/ssh-connection-generation'
|
||||
import { renameLocalPathSerializedByDestination } from '../../destination-serialized-local-rename'
|
||||
import { assertNotExists, rethrowWithUserMessage } from '../filesystem-create-path-guards'
|
||||
import { assertNotExists, rethrowWithUserMessage } from './filesystem-create-path-guards'
|
||||
import type {
|
||||
ImportItemResult,
|
||||
ResolveDroppedPathsResult,
|
||||
StagedExternalImportSource
|
||||
} from '../../../shared/filesystem-import-result-types'
|
||||
import { importOneSource } from '../filesystem-import-local'
|
||||
import { importOneSource } from './filesystem-import-local'
|
||||
import {
|
||||
stagedRuntimeUploadByteLength,
|
||||
stageOneSourceForRuntimeUpload
|
||||
} from '../filesystem-runtime-upload-staging'
|
||||
} from './filesystem-runtime-upload-staging'
|
||||
import { streamExternalFileToRuntime } from '../runtime-upload-file-stream'
|
||||
import { abortWhenRendererGone } from '../renderer-lifetime-abort'
|
||||
import { sweepAbandonedRuntimeUploadTempPath } from '../runtime-upload-temp-sweep'
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ import { tmpdir } from 'node:os'
|
||||
import { join, resolve } from 'node:path'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import type { Store } from '../persistence'
|
||||
import type { Repo } from '../../shared/repo-types'
|
||||
import type { Store } from '../../persistence/loading-store/store'
|
||||
import type { Repo } from '../../../shared/repo-types'
|
||||
import { PATH_ACCESS_DENIED_MESSAGE, resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { isDescendantOrEqual } from './filesystem-path-containment'
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { resolve, relative, isAbsolute, sep, dirname } from 'node:path'
|
||||
import { statSync } from 'node:fs'
|
||||
import { realpath } from 'node:fs/promises'
|
||||
import { isDefinitiveAbsence } from '../../shared/definitive-filesystem-absence'
|
||||
import { isDefinitiveAbsence } from '../../../shared/definitive-filesystem-absence'
|
||||
|
||||
/** Check native-path containment; accept Unicode-equivalent spellings only after proving filesystem identity. */
|
||||
export function isDescendantOrEqual(resolvedTarget: string, resolvedBase: string): boolean {
|
||||
@@ -4,8 +4,8 @@ import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, expect, it } from 'vitest'
|
||||
import type { Store } from '../../persistence/loading-store/store'
|
||||
import { listQuickOpenFiles } from '../filesystem-list-files'
|
||||
import { searchQuickOpenFilePaths } from '../filesystem-search-file-paths'
|
||||
import { listQuickOpenFiles } from './filesystem-list-files'
|
||||
import { searchQuickOpenFilePaths } from './filesystem-search-file-paths'
|
||||
|
||||
const fixtures: string[] = []
|
||||
afterEach(async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { classifyFilesystemDirectoryEntries } from '../filesystem-symlink-directory-entries'
|
||||
import { classifyFilesystemDirectoryEntries } from './filesystem-symlink-directory-entries'
|
||||
import { markdownDocumentsFromRelativePaths } from '../../../shared/markdown-document-paths'
|
||||
import {
|
||||
capturePathExistence,
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
resolveDesktopAuthorizedPath,
|
||||
resolveLocalFileRequestPath
|
||||
} from '../local-file-access-resolution'
|
||||
import { isPathAbsentError } from '../filesystem-path-containment'
|
||||
import { isPathAbsentError } from './filesystem-path-containment'
|
||||
import { listMarkdownDocuments } from '../markdown-documents'
|
||||
import { getLocalGitOptionsForRegisteredWorktree } from '../local-worktree-runtime-options'
|
||||
import { recordCrashBreadcrumb } from '../../crash-reporting/crash-breadcrumb-store'
|
||||
|
||||
+2
-2
@@ -2,12 +2,12 @@ import { lstat, mkdtemp, mkdir, rm, symlink, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type * as RuntimeImportLimits from './runtime-import-limits'
|
||||
import type * as RuntimeImportLimits from '../runtime-import-limits'
|
||||
|
||||
type RuntimeImportLimitsModule = typeof RuntimeImportLimits
|
||||
|
||||
// Scale down gigabyte ceilings: NTFS truncate may allocate the entire oversized fixture.
|
||||
vi.mock('./runtime-import-limits', async (importOriginal) => ({
|
||||
vi.mock('../runtime-import-limits', async (importOriginal) => ({
|
||||
...(await importOriginal<RuntimeImportLimitsModule>()),
|
||||
REMOTE_IMPORT_MAX_FILE_BYTES: 4 * 1024,
|
||||
REMOTE_IMPORT_MAX_TOTAL_BYTES: 16 * 1024
|
||||
+3
-3
@@ -2,16 +2,16 @@ import {
|
||||
formatByteCeiling,
|
||||
REMOTE_IMPORT_MAX_FILE_BYTES,
|
||||
REMOTE_IMPORT_MAX_TOTAL_BYTES
|
||||
} from './runtime-import-limits'
|
||||
} from '../runtime-import-limits'
|
||||
import { constants } from 'node:fs'
|
||||
import { lstat, open, readdir, realpath, type FileHandle } from 'node:fs/promises'
|
||||
import { basename, extname, isAbsolute, join, relative, resolve, sep } from 'node:path'
|
||||
import { classifyImportSource } from './filesystem-import-source-stat'
|
||||
import { detectImageFileSignature, IMAGE_SIGNATURE_BYTES } from '../image-file-signature'
|
||||
import { detectImageFileSignature, IMAGE_SIGNATURE_BYTES } from '../../image-file-signature'
|
||||
import type {
|
||||
StagedExternalImportEntry,
|
||||
StagedExternalImportSource
|
||||
} from '../../shared/filesystem-import-result-types'
|
||||
} from '../../../shared/filesystem-import-result-types'
|
||||
|
||||
class RuntimeUploadSymlinkError extends Error {}
|
||||
|
||||
+8
-8
@@ -1,11 +1,11 @@
|
||||
import { EventEmitter } from 'node:events'
|
||||
import type { ChildProcess } from 'node:child_process'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { Store } from '../persistence'
|
||||
import type * as GitRunner from '../git/runner'
|
||||
import type * as BundledRipgrepPath from '../ripgrep/bundled-ripgrep-path'
|
||||
import { isFileListingCancellation } from '../../shared/file-listing-cancellation'
|
||||
import { RipgrepUnavailableError } from '../../shared/ripgrep-process-availability'
|
||||
import type { Store } from '../../persistence/loading-store/store'
|
||||
import type * as GitRunner from '../../git/runner'
|
||||
import type * as BundledRipgrepPath from '../../ripgrep/bundled-ripgrep-path'
|
||||
import { isFileListingCancellation } from '../../../shared/file-listing-cancellation'
|
||||
import { RipgrepUnavailableError } from '../../../shared/ripgrep-process-availability'
|
||||
|
||||
const {
|
||||
bundledRipgrepCommandMock,
|
||||
@@ -19,7 +19,7 @@ const {
|
||||
wslAwareSpawnMock: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('../git/runner', async (importOriginal) => ({
|
||||
vi.mock('../../git/runner', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof GitRunner>()),
|
||||
wslAwareSpawn: wslAwareSpawnMock
|
||||
}))
|
||||
@@ -28,12 +28,12 @@ vi.mock('./filesystem-auth', () => ({
|
||||
resolveAuthorizedPath: resolveAuthorizedPathMock
|
||||
}))
|
||||
|
||||
vi.mock('../ripgrep/bundled-ripgrep-path', async (importOriginal) => ({
|
||||
vi.mock('../../ripgrep/bundled-ripgrep-path', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof BundledRipgrepPath>()),
|
||||
bundledRipgrepCommand: bundledRipgrepCommandMock
|
||||
}))
|
||||
|
||||
vi.mock('./local-worktree-runtime-options', () => ({
|
||||
vi.mock('../local-worktree-runtime-options', () => ({
|
||||
getLocalGitOptionsForRegisteredWorktree: getLocalGitOptionsForRegisteredWorktreeMock
|
||||
}))
|
||||
|
||||
+16
-13
@@ -1,16 +1,19 @@
|
||||
import { getQuickOpenRgOutputMode } from '../../shared/quick-open-ripgrep-output-mode'
|
||||
import { RipgrepFilenameDecoder } from '../../shared/ripgrep-filename-decoder'
|
||||
import { getQuickOpenRgOutputMode } from '../../../shared/quick-open-ripgrep-output-mode'
|
||||
import { RipgrepFilenameDecoder } from '../../../shared/ripgrep-filename-decoder'
|
||||
import { sep } from 'node:path'
|
||||
import type { RuntimeStore } from '../runtime/runtime-store-contract'
|
||||
import { fileListingCancellationError } from '../../shared/file-listing-cancellation'
|
||||
import type { RuntimeStore } from '../../runtime/runtime-store-contract'
|
||||
import { fileListingCancellationError } from '../../../shared/file-listing-cancellation'
|
||||
import {
|
||||
buildExcludePathPrefixes,
|
||||
buildRgArgsForQuickOpen,
|
||||
normalizeQuickOpenRgLine,
|
||||
shouldExcludeQuickOpenRelPath,
|
||||
shouldIncludeQuickOpenPath
|
||||
} from '../../shared/quick-open-filter'
|
||||
import { isQuickOpenQueryTooLarge, QuickOpenPathRanker } from '../../shared/quick-open-path-search'
|
||||
} from '../../../shared/quick-open-filter'
|
||||
import {
|
||||
isQuickOpenQueryTooLarge,
|
||||
QuickOpenPathRanker
|
||||
} from '../../../shared/quick-open-path-search'
|
||||
import {
|
||||
absorbPendingRipgrepSpawnError,
|
||||
isRipgrepUnavailableExit,
|
||||
@@ -22,14 +25,14 @@ import {
|
||||
ripgrepMissingCwdError,
|
||||
RipgrepLaunchFailureError,
|
||||
RipgrepUnavailableError
|
||||
} from '../../shared/ripgrep-process-availability'
|
||||
import { toWindowsWslPath } from '../wsl'
|
||||
import { resolveBundledRipgrepWslRouting } from '../ripgrep/bundled-ripgrep-wsl-routing'
|
||||
} from '../../../shared/ripgrep-process-availability'
|
||||
import { toWindowsWslPath } from '../../../shared/wsl-paths'
|
||||
import { resolveBundledRipgrepWslRouting } from '../../ripgrep/bundled-ripgrep-wsl-routing'
|
||||
import { resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { getLocalGitOptionsForRegisteredWorktree } from './local-worktree-runtime-options'
|
||||
import { QuickOpenSubprocessPathAccumulator } from '../../shared/quick-open-subprocess-path-accumulator'
|
||||
import { bundledRipgrepUnavailableError } from '../ripgrep/bundled-ripgrep-path'
|
||||
import { spawnBundledRipgrep } from '../ripgrep/bundled-ripgrep-spawn'
|
||||
import { getLocalGitOptionsForRegisteredWorktree } from '../local-worktree-runtime-options'
|
||||
import { QuickOpenSubprocessPathAccumulator } from '../../../shared/quick-open-subprocess-path-accumulator'
|
||||
import { bundledRipgrepUnavailableError } from '../../ripgrep/bundled-ripgrep-path'
|
||||
import { spawnBundledRipgrep } from '../../ripgrep/bundled-ripgrep-spawn'
|
||||
|
||||
export type QuickOpenFilePathSearchResult = {
|
||||
paths: string[]
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ipcMain } from 'electron'
|
||||
import { listQuickOpenFiles } from '../filesystem-list-files'
|
||||
import { listQuickOpenFiles } from './filesystem-list-files'
|
||||
import {
|
||||
isFileNameFilterQueryTooLarge,
|
||||
pathMatchesFileNameFilterTokens,
|
||||
|
||||
+9
-9
@@ -1,7 +1,7 @@
|
||||
import { EventEmitter } from 'node:events'
|
||||
import type { ChildProcess } from 'node:child_process'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type * as BundledRipgrepPath from '../ripgrep/bundled-ripgrep-path'
|
||||
import type * as BundledRipgrepPath from '../../ripgrep/bundled-ripgrep-path'
|
||||
|
||||
const {
|
||||
handleMock,
|
||||
@@ -33,12 +33,12 @@ vi.mock('electron', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
vi.mock('../git/runner', () => ({
|
||||
vi.mock('../../git/runner', () => ({
|
||||
gitExecFileAsync: vi.fn(),
|
||||
wslAwareSpawn: wslAwareSpawnMock
|
||||
}))
|
||||
|
||||
vi.mock('../wsl', () => ({
|
||||
vi.mock('../../wsl', () => ({
|
||||
parseWslPath: parseWslPathMock,
|
||||
toWindowsWslPath: toWindowsWslPathMock
|
||||
}))
|
||||
@@ -52,7 +52,7 @@ vi.mock('./filesystem-path-containment', () => ({
|
||||
validateGitRelativeFilePath: vi.fn((value: string) => value)
|
||||
}))
|
||||
|
||||
vi.mock('./registered-worktree-roots-cache', () => ({
|
||||
vi.mock('../registered-worktree-roots-cache', () => ({
|
||||
resolveRegisteredWorktreePath: vi.fn(async (value: string) => value)
|
||||
}))
|
||||
|
||||
@@ -60,24 +60,24 @@ vi.mock('./filesystem-list-files', () => ({
|
||||
listQuickOpenFiles: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('./filesystem/filesystem-mutations', () => ({
|
||||
vi.mock('./filesystem-mutations', () => ({
|
||||
registerFilesystemMutationHandlers: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('../ripgrep/bundled-ripgrep-path', async (importOriginal) => ({
|
||||
vi.mock('../../ripgrep/bundled-ripgrep-path', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof BundledRipgrepPath>()),
|
||||
bundledRipgrepCommand: bundledRipgrepCommandMock
|
||||
}))
|
||||
|
||||
vi.mock('./local-worktree-runtime-options', () => ({
|
||||
vi.mock('../local-worktree-runtime-options', () => ({
|
||||
getLocalGitOptionsForRegisteredWorktree: getLocalGitOptionsForRegisteredWorktreeMock
|
||||
}))
|
||||
|
||||
vi.mock('./markdown-documents', () => ({
|
||||
vi.mock('../markdown-documents', () => ({
|
||||
listMarkdownDocuments: vi.fn()
|
||||
}))
|
||||
|
||||
import { registerFilesystemHandlers } from './filesystem/filesystem'
|
||||
import { registerFilesystemHandlers } from './filesystem'
|
||||
|
||||
function createMockProcess(): ChildProcess {
|
||||
const p = new EventEmitter() as unknown as ChildProcess
|
||||
@@ -11,7 +11,7 @@ vi.mock('../../project-runtime-git-options', () => ({
|
||||
vi.mock('../registered-worktree-roots-cache', () => ({
|
||||
resolveRegisteredWorktreePath: async (path: string) => path
|
||||
}))
|
||||
vi.mock('../filesystem-auth', () => ({ resolveAuthorizedPath: vi.fn() }))
|
||||
vi.mock('./filesystem-auth', () => ({ resolveAuthorizedPath: vi.fn() }))
|
||||
import { getRepoForSourceControlAi } from './filesystem-source-control-ai-targets'
|
||||
|
||||
const repo: Repo = {
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { CommitMessageAgentRuntimeTarget } from '../../text-generation/comm
|
||||
import type { CommitMessageGenerationTarget } from '../../text-generation/commit-message-text-generation'
|
||||
import { resolve } from 'node:path'
|
||||
import { listRepoWorktreeGraph } from '../../repo-worktrees'
|
||||
import { resolveAuthorizedPath } from '../filesystem-auth'
|
||||
import { resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { resolveRegisteredWorktreePath } from '../registered-worktree-roots-cache'
|
||||
import { splitWorktreeId } from '../../../shared/worktree/id'
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import type { Dirent } from 'node:fs'
|
||||
import { stat } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import type { DirEntry } from '../../shared/filesystem-entry-types'
|
||||
import { mapWithConcurrency } from '../../shared/map-with-concurrency'
|
||||
import type { DirEntry } from '../../../shared/filesystem-entry-types'
|
||||
import { mapWithConcurrency } from '../../../shared/map-with-concurrency'
|
||||
|
||||
export function classifyFilesystemDirectoryEntries(
|
||||
dirPath: string,
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
resolveDesktopAuthorizedPath,
|
||||
resolveLocalWriteRequestPath
|
||||
} from '../local-file-access-resolution'
|
||||
import { isENOENT } from '../filesystem-path-containment'
|
||||
import { isENOENT } from './filesystem-path-containment'
|
||||
import { registerFilesystemMutationHandlers } from './filesystem-mutations'
|
||||
import { registerAgentSessionAttachmentUploadHandlers } from '../agent-session-attachment-upload-ipc'
|
||||
import type { FilesystemHandlerContext } from './filesystem-handler-context'
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
import { getBranchCompare, getCommitCompare } from '../../../git/status'
|
||||
import { resolveRegisteredWorktreePath } from '../../registered-worktree-roots-cache'
|
||||
import { getLocalGitOptionsForRegisteredWorktree } from '../../local-worktree-runtime-options'
|
||||
import { validateFullGitObjectId } from '../../filesystem-path-containment'
|
||||
import { validateFullGitObjectId } from '../filesystem-path-containment'
|
||||
import type { FilesystemHandlerContext } from '../filesystem-handler-context'
|
||||
import type { GitAdmissionTier } from '../../../git/command-runner/git-exec-options'
|
||||
import { requireReachableGitRoute } from '../../../providers/execution-host-provider-dispatch'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { constants, type Stats } from 'node:fs'
|
||||
import { open, type FileHandle } from 'node:fs/promises'
|
||||
import { isENOENT } from '../filesystem-path-containment'
|
||||
import { isENOENT } from './filesystem-path-containment'
|
||||
|
||||
export const NOT_A_REGULAR_FILE_MESSAGE = 'Not a regular file'
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { isFolderRepo } from '../../../shared/repo-kind'
|
||||
import { inspectSetupScriptImportCandidates } from '../../../shared/setup-script-imports'
|
||||
import { joinWorktreeRelativePath } from '../../runtime/runtime-relative-paths'
|
||||
import { readFile, stat } from 'node:fs/promises'
|
||||
import { isENOENT } from '../filesystem-path-containment'
|
||||
import { isENOENT } from '../filesystem/filesystem-path-containment'
|
||||
import { resolveRepoForExecutionHost } from '../worktrees/repo-host-ownership'
|
||||
import type { WorktreeIpcContext } from '../worktrees/worktree-ipc-context'
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { installFakeAppEnvironment } from '../../../config/scripts/vitest-host-ports-setup'
|
||||
import type { Store } from '../persistence'
|
||||
import type * as RepoWorktrees from '../repo-worktrees'
|
||||
import { resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { resolveAuthorizedPath } from './filesystem/filesystem-auth'
|
||||
import {
|
||||
resolveDesktopAuthorizedPath,
|
||||
resolveLocalFileRequestPath,
|
||||
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
PATH_ACCESS_DENIED_MESSAGE,
|
||||
resolveAuthorizedPath,
|
||||
type ResolveAuthorizedPathOptions
|
||||
} from './filesystem-auth'
|
||||
import { isDescendantOrEqual } from './filesystem-path-containment'
|
||||
} from './filesystem/filesystem-auth'
|
||||
import { isDescendantOrEqual } from './filesystem/filesystem-path-containment'
|
||||
import { PREVIEWABLE_BINARY_MIME_TYPES } from './filesystem/filesystem-file-content-inspection'
|
||||
import { getDefaultFloatingWorkspacePath } from './floating-workspace-directory'
|
||||
import {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { isDescendantOrEqual } from './filesystem/filesystem-path-containment'
|
||||
|
||||
export function findRegisteredWorktreeRoot(
|
||||
targetPath: string,
|
||||
registeredWorktreeRoots: Iterable<string>
|
||||
): string | null {
|
||||
let bestRoot: string | null = null
|
||||
for (const root of registeredWorktreeRoots) {
|
||||
if (isDescendantOrEqual(targetPath, root) && (!bestRoot || root.length > bestRoot.length)) {
|
||||
bestRoot = root
|
||||
}
|
||||
}
|
||||
return bestRoot
|
||||
}
|
||||
@@ -15,10 +15,9 @@ vi.mock('./worktree-logic', () => ({
|
||||
getWorktreePathSettings: vi.fn()
|
||||
}))
|
||||
vi.mock('../project-runtime-git-options', () => ({
|
||||
getWorktreeMirrorDistroForRuntime: vi.fn(),
|
||||
resolveLocalProjectRuntimesForRepos: vi.fn()
|
||||
getWorktreeMirrorDistroForRuntime: vi.fn()
|
||||
}))
|
||||
import { resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { resolveAuthorizedPath } from './filesystem/filesystem-auth'
|
||||
import {
|
||||
__resetCreatedWorktreeRootsForTests,
|
||||
invalidateAuthorizedRootsCache,
|
||||
|
||||
@@ -15,10 +15,9 @@ vi.mock('./worktree-logic', () => ({
|
||||
getWorktreePathSettings: vi.fn()
|
||||
}))
|
||||
vi.mock('../project-runtime-git-options', () => ({
|
||||
getWorktreeMirrorDistroForRuntime: vi.fn(),
|
||||
resolveLocalProjectRuntimesForRepos: vi.fn()
|
||||
getWorktreeMirrorDistroForRuntime: vi.fn()
|
||||
}))
|
||||
import { resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { resolveAuthorizedPath } from './filesystem/filesystem-auth'
|
||||
import {
|
||||
__resetCreatedWorktreeRootsForTests,
|
||||
invalidateAuthorizedRootsCache,
|
||||
|
||||
@@ -14,7 +14,7 @@ vi.mock('../repo-worktrees', () => ({
|
||||
vi.mock('../local-project-runtime-resolution', () => ({
|
||||
resolveLocalProjectRuntimesForRepos: mocks.runtimes
|
||||
}))
|
||||
import { PATH_ACCESS_DENIED_MESSAGE, resolveAuthorizedPath } from './filesystem-auth'
|
||||
import { PATH_ACCESS_DENIED_MESSAGE, resolveAuthorizedPath } from './filesystem/filesystem-auth'
|
||||
import {
|
||||
__resetCreatedWorktreeRootsForTests,
|
||||
invalidateAuthorizedRootsCache,
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import { resolve } from 'node:path'
|
||||
import { findRegisteredWorktreeRoot } from './registered-worktree-root-match'
|
||||
import type { Repo } from '../../shared/repo-types'
|
||||
import type { RegisteredWorktreeRootStore as Store } from './registered-worktree-root-store'
|
||||
import {
|
||||
listWorktreeRootsWithConcurrency,
|
||||
pruneCreatedWorktreeRoots
|
||||
} from './registered-worktree-root-probes'
|
||||
import { isDescendantOrEqual, normalizeExistingPath } from './filesystem-path-containment'
|
||||
import {
|
||||
isDescendantOrEqual,
|
||||
normalizeExistingPath
|
||||
} from './filesystem/filesystem-path-containment'
|
||||
import {
|
||||
findOwnersListedThroughAnotherGit,
|
||||
shouldRelistOwner
|
||||
@@ -283,7 +287,7 @@ export async function isPathAllowedByCanonicalRegisteredRoot(
|
||||
return false
|
||||
}
|
||||
synchronizeOwners(store)
|
||||
const textualRoot = findRegisteredWorktreeRoot(sourcePath)
|
||||
const textualRoot = findRegisteredWorktreeRoot(sourcePath, registeredWorktreeRoots)
|
||||
if (!textualRoot) {
|
||||
return false
|
||||
}
|
||||
@@ -314,13 +318,3 @@ export async function isPathAllowedByCanonicalRegisteredRoot(
|
||||
}
|
||||
return allowed
|
||||
}
|
||||
|
||||
function findRegisteredWorktreeRoot(targetPath: string): string | null {
|
||||
let bestRoot: string | null = null
|
||||
for (const root of registeredWorktreeRoots) {
|
||||
if (isDescendantOrEqual(targetPath, root) && (!bestRoot || root.length > bestRoot.length)) {
|
||||
bestRoot = root
|
||||
}
|
||||
}
|
||||
return bestRoot
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ vi.mock('./runtime-environments/runtime-environment-transport-routing', () => ({
|
||||
callRuntimeEnvironment: (...args: Parameters<typeof callRuntimeEnvironment>) =>
|
||||
callRuntimeEnvironment(...args)
|
||||
}))
|
||||
// Lower test caps avoid allocating gigabytes on Windows; see filesystem-runtime-upload-staging.test.ts.
|
||||
// Lower test caps avoid allocating gigabytes on Windows; see filesystem/filesystem-runtime-upload-staging.test.ts.
|
||||
vi.mock('./runtime-import-limits', async (importOriginal) => ({
|
||||
...(await importOriginal<RuntimeImportLimitsModule>()),
|
||||
REMOTE_IMPORT_MAX_FILE_BYTES: 2 * 1024 * 1024
|
||||
|
||||
@@ -39,7 +39,8 @@ vi.mock('./runtime-environments/runtime-environment-transport-routing', () => ({
|
||||
|
||||
const { RUNTIME_UPLOAD_SLICE_BYTES, streamExternalFileToRuntime } =
|
||||
await import('./runtime-upload-file-stream')
|
||||
const { stageOneSourceForRuntimeUpload } = await import('./filesystem-runtime-upload-staging')
|
||||
const { stageOneSourceForRuntimeUpload } =
|
||||
await import('./filesystem/filesystem-runtime-upload-staging')
|
||||
const { REMOTE_IMPORT_MAX_FILE_BYTES, REMOTE_IMPORT_MAX_TOTAL_BYTES, formatByteCeiling } =
|
||||
await import('./runtime-import-limits')
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import type {
|
||||
AgentSessionReadVisualResult,
|
||||
AgentSessionVisualReadError
|
||||
} from '../../shared/rpc-contract/agent-session-visual-params'
|
||||
import { isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import { readLocalFileBounded } from '../ipc/filesystem/local-regular-file-read'
|
||||
|
||||
// O_NOFOLLOW prevents final-component swaps; Windows relies on lstat and post-open identity checks.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lstat, realpath } from 'node:fs/promises'
|
||||
import { basename, dirname, isAbsolute, relative, resolve } from 'node:path'
|
||||
import { isDescendantOrEqual, isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { isDescendantOrEqual, isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import { isWslUncPath } from '../../shared/wsl-paths'
|
||||
import { needsWslHostResolution } from './host-readable-transcript-path'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { readOpenCodeNativeChatTranscriptFull } from './transcript-opencode'
|
||||
import { isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import type {
|
||||
AgentType,
|
||||
NativeChatMessage,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { readOpenCodeNativeChatTranscriptTail } from './transcript-opencode'
|
||||
import { isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import type {
|
||||
AgentType,
|
||||
NativeChatMessage,
|
||||
|
||||
@@ -3,10 +3,13 @@ import { dirname } from 'node:path'
|
||||
import { throwIfSignalAborted, waitForPromiseWithSignal } from '../../shared/abort-signal-reason'
|
||||
import { readAuthorizedDocPreviewFile } from '../../shared/doc-preview-file-access'
|
||||
import { renameLocalPathSerializedByDestination } from '../destination-serialized-local-rename'
|
||||
import type { resolveAuthorizedPath as ResolveAuthorizedPath } from '../ipc/filesystem-auth'
|
||||
import { isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { assertNotExists, rethrowWithUserMessage } from '../ipc/filesystem-create-path-guards'
|
||||
import { classifyFilesystemDirectoryEntries } from '../ipc/filesystem-symlink-directory-entries'
|
||||
import type { resolveAuthorizedPath as ResolveAuthorizedPath } from '../ipc/filesystem/filesystem-auth'
|
||||
import { isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import {
|
||||
assertNotExists,
|
||||
rethrowWithUserMessage
|
||||
} from '../ipc/filesystem/filesystem-create-path-guards'
|
||||
import { classifyFilesystemDirectoryEntries } from '../ipc/filesystem/filesystem-symlink-directory-entries'
|
||||
import { getLocalGitOptionsForRegisteredWorktree } from '../ipc/local-worktree-runtime-options'
|
||||
import { listMarkdownDocuments } from '../ipc/markdown-documents'
|
||||
import type { RuntimeStore } from '../runtime/runtime-store-contract'
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { lstat } from 'node:fs/promises'
|
||||
import { basename, dirname } from 'node:path'
|
||||
import type { RuntimeStore } from '../runtime-store-contract'
|
||||
import { resolveAuthorizedPath, type ResolveAuthorizedPathOptions } from '../../ipc/filesystem-auth'
|
||||
import { isENOENT } from '../../ipc/filesystem-path-containment'
|
||||
import {
|
||||
resolveAuthorizedPath,
|
||||
type ResolveAuthorizedPathOptions
|
||||
} from '../../ipc/filesystem/filesystem-auth'
|
||||
import { isENOENT } from '../../ipc/filesystem/filesystem-path-containment'
|
||||
import { nativeChatScratchRootFor } from '../../native-chat/native-chat-scratch-folder'
|
||||
import { getProfileUserDataPath } from '../../orca-profiles/profile-storage-paths'
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import type { RuntimeFileCommandHost } from './file-command-host'
|
||||
import type { RuntimeFileOpenResult } from '../../../shared/runtime-types'
|
||||
import type { RuntimeNavigationTarget } from '../../../shared/runtime-navigation'
|
||||
import { joinWorktreeRelativePath } from '../runtime-relative-paths'
|
||||
import { isENOENT } from '../../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../../ipc/filesystem/filesystem-path-containment'
|
||||
import {
|
||||
requireRuntimeFileProvider,
|
||||
resolveFileExplorerPath,
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
capturePathExistence,
|
||||
type PathExistenceResult
|
||||
} from '../../../shared/path-existence-batch'
|
||||
import { isPathAbsentError } from '../../ipc/filesystem-path-containment'
|
||||
import { isPathAbsentError } from '../../ipc/filesystem/filesystem-path-containment'
|
||||
import {
|
||||
requireRuntimeFileProvider,
|
||||
type RuntimeFileExplorerPath,
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
throwIfSignalAborted,
|
||||
waitForPromiseWithSignal
|
||||
} from '../../../../shared/abort-signal-reason'
|
||||
import { listQuickOpenFiles } from '../../../ipc/filesystem-list-files'
|
||||
import { searchQuickOpenFilePaths as searchHostQuickOpenFilePaths } from '../../../ipc/filesystem-search-file-paths'
|
||||
import { listQuickOpenFiles } from '../../../ipc/filesystem/filesystem-list-files'
|
||||
import { searchQuickOpenFilePaths as searchHostQuickOpenFilePaths } from '../../../ipc/filesystem/filesystem-search-file-paths'
|
||||
import { isMobileBinaryPath, isSafeMobileRelativePath } from '../mobile-file-kind'
|
||||
import {
|
||||
requireRuntimeFileProvider,
|
||||
|
||||
@@ -12,7 +12,7 @@ import type { RuntimeFileCommandHost } from '../file-command-host'
|
||||
import { stat } from 'node:fs/promises'
|
||||
import type { DirEntry, FsChangeEvent } from '../../../../shared/filesystem-entry-types'
|
||||
import { sortDirEntries } from '../../../../shared/file-name-sort'
|
||||
import { resolveAuthorizedPath } from '../../../ipc/filesystem-auth'
|
||||
import { resolveAuthorizedPath } from '../../../ipc/filesystem/filesystem-auth'
|
||||
import { resolveRuntimeAuthorizedPath } from '../chat-scratch-file-root'
|
||||
import { watchWindowsRuntimeFileExplorer } from './windows-file-watch'
|
||||
import { beginWatcherInstall } from '../../../ipc/watcher-removal-gate'
|
||||
|
||||
@@ -14,7 +14,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -21,7 +21,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { vi } from 'vitest'
|
||||
import type { Mock } from 'vitest'
|
||||
import type * as Fs from 'node:fs'
|
||||
import type * as FsPromises from 'node:fs/promises'
|
||||
import type * as FilesystemAuth from '../ipc/filesystem-auth'
|
||||
import type * as FilesystemAuth from '../ipc/filesystem/filesystem-auth'
|
||||
import type * as GitRunner from '../git/runner'
|
||||
import type * as BundledRipgrepPath from '../ripgrep/bundled-ripgrep-path'
|
||||
|
||||
@@ -75,7 +75,7 @@ export const fileWatcherHostMock = {
|
||||
}
|
||||
|
||||
export async function filesystemAuthModuleMock() {
|
||||
const actual = await vi.importActual<typeof FilesystemAuth>('../ipc/filesystem-auth')
|
||||
const actual = await vi.importActual<typeof FilesystemAuth>('../ipc/filesystem/filesystem-auth')
|
||||
return {
|
||||
...actual,
|
||||
resolveAuthorizedPath: resolveAuthorizedPathMock
|
||||
|
||||
@@ -18,7 +18,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -20,7 +20,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -20,7 +20,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -21,7 +21,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -23,7 +23,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -20,7 +20,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -20,7 +20,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -18,7 +18,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -14,7 +14,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { EventEmitter } from 'node:events'
|
||||
import type * as Fs from 'node:fs'
|
||||
import type * as FsPromises from 'node:fs/promises'
|
||||
import type * as FilesystemAuth from '../ipc/filesystem-auth'
|
||||
import type * as FilesystemAuth from '../ipc/filesystem/filesystem-auth'
|
||||
import type { FsChangeEvent } from '../../shared/filesystem-entry-types'
|
||||
import { WatcherProcessFailure } from '../ipc/filesystem/watcher-process/parcel-watcher-process-failure'
|
||||
import { acquireWatcherRemovalGate } from '../ipc/watcher-removal-gate'
|
||||
@@ -42,8 +42,8 @@ vi.mock('./file-watcher-host', () => ({
|
||||
watchFileExplorerInWatcherProcess: watchInWatcherProcessMock
|
||||
}))
|
||||
|
||||
vi.mock('../ipc/filesystem-auth', async () => {
|
||||
const actual = await vi.importActual<typeof FilesystemAuth>('../ipc/filesystem-auth')
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () => {
|
||||
const actual = await vi.importActual<typeof FilesystemAuth>('../ipc/filesystem/filesystem-auth')
|
||||
return {
|
||||
...actual,
|
||||
resolveAuthorizedPath: resolveAuthorizedPathMock
|
||||
|
||||
@@ -13,7 +13,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { expect, vi } from 'vitest'
|
||||
import type { Mock } from 'vitest'
|
||||
import type * as GitUsernameModule from '../../git/git-username'
|
||||
import type * as FilesystemPathContainmentModule from '../../ipc/filesystem-path-containment'
|
||||
import type * as FilesystemPathContainmentModule from '../../ipc/filesystem/filesystem-path-containment'
|
||||
import { reviewHeadRemoteRefComponent } from '../../../shared/review-head-tracking-ref'
|
||||
|
||||
export const ORIGIN_REMOTE_URL = 'git@example.com:group/repo.git'
|
||||
@@ -349,7 +349,7 @@ vi.mock('../../ipc/worktree-logic', async (importOriginal) => {
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('../../ipc/filesystem-auth', () => ({
|
||||
vi.mock('../../ipc/filesystem/filesystem-auth', () => ({
|
||||
resolveAuthorizedPath: vi.fn(async (pathValue: string) => pathValue)
|
||||
}))
|
||||
|
||||
@@ -362,9 +362,9 @@ vi.mock('../../ipc/registered-worktree-roots-scoped-invalidation', () => ({
|
||||
}))
|
||||
|
||||
// Relay-rebuilt ENOENT errors may retain only the message.
|
||||
vi.mock('../../ipc/filesystem-path-containment', async () => {
|
||||
vi.mock('../../ipc/filesystem/filesystem-path-containment', async () => {
|
||||
const actual = await vi.importActual<typeof FilesystemPathContainmentModule>(
|
||||
'../../ipc/filesystem-path-containment'
|
||||
'../../ipc/filesystem/filesystem-path-containment'
|
||||
)
|
||||
return { isENOENT: actual.isENOENT }
|
||||
})
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
useRuntimeFileCommandsLifecycle
|
||||
} from './orca-runtime-files-test-harness'
|
||||
const { localList } = vi.hoisted(() => ({ localList: vi.fn() }))
|
||||
vi.mock('../ipc/filesystem-list-files', () => ({ listQuickOpenFiles: localList }))
|
||||
vi.mock('../ipc/filesystem/filesystem-list-files', () => ({ listQuickOpenFiles: localList }))
|
||||
|
||||
describe('runtime producer listing budgets', () => {
|
||||
useRuntimeFileCommandsLifecycle()
|
||||
|
||||
@@ -20,7 +20,7 @@ vi.mock('./files/file-target', () => ({
|
||||
resolveFileExplorerPath: mocks.resolvePath,
|
||||
requireRuntimeFileProvider: mocks.provider
|
||||
}))
|
||||
vi.mock('../ipc/filesystem-auth', () => ({ resolveAuthorizedPath: mocks.authorize }))
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', () => ({ resolveAuthorizedPath: mocks.authorize }))
|
||||
vi.mock('node:fs/promises', async (importOriginal) => ({
|
||||
...(await importOriginal()),
|
||||
mkdir: mocks.mkdir,
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
getDefaultTabCommandTrustContent,
|
||||
getEffectiveSetupRunPolicy
|
||||
} from '../effective-hook-config'
|
||||
import { isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import { isFolderRepo } from '../../shared/repo-kind'
|
||||
import { inspectSetupScriptImportCandidates } from '../../shared/setup-script-imports'
|
||||
import { joinWorktreeRelativePath } from './runtime-relative-paths'
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { Repo } from '../../shared/repo-types'
|
||||
import { gitExecFileAsync, awaitWindowsHostGitEnvironmentReady } from '../git/runner'
|
||||
import { getRepoName, inspectGitRepoForRegistrationAsync } from '../git/repo'
|
||||
import { invalidateAuthorizedRootsCache } from '../ipc/registered-worktree-roots-cache'
|
||||
import { isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import { findProjectAtSameRealPath } from '../project-realpath-identity'
|
||||
import { detectRepoIconAndUpstream } from '../repo-icon-autodetect'
|
||||
import { prepareLocalWorktreeRootForRepo } from '../worktree-root-preparation'
|
||||
|
||||
@@ -14,7 +14,7 @@ vi.mock(
|
||||
'./file-watcher-host',
|
||||
async () => (await import('./orca-runtime-files-mock-registry')).fileWatcherHostMock
|
||||
)
|
||||
vi.mock('../ipc/filesystem-auth', async () =>
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', async () =>
|
||||
(await import('./orca-runtime-files-mock-registry')).filesystemAuthModuleMock()
|
||||
)
|
||||
vi.mock('../git/runner', async () =>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { stat } from 'node:fs/promises'
|
||||
import { FOLDER_WORKSPACE_INSTANCE_SEPARATOR } from '../../shared/worktree/id'
|
||||
import type { Repo } from '../../shared/repo-types'
|
||||
import type { Worktree } from '../../shared/worktree/types'
|
||||
import { isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import {
|
||||
getLocalWorktreePathAccess,
|
||||
toLocalWorktreeRuntimePath
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { constants } from 'node:fs'
|
||||
import { lstat, open, realpath } from 'node:fs/promises'
|
||||
import { isAbsolute, win32 } from 'node:path'
|
||||
import { isDescendantOrEqual } from '../ipc/filesystem-path-containment'
|
||||
import { isDescendantOrEqual } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import {
|
||||
parseWslUncPath,
|
||||
toLinuxPath,
|
||||
|
||||
@@ -8,7 +8,7 @@ import { homedir } from 'node:os'
|
||||
import { provenancePathCandidate, resolveTerminalAbsolutePath } from './terminal-file-path'
|
||||
import { requireRuntimeFileProvider, runtimeFileRouteForTarget } from '../files/file-target'
|
||||
import { isSafeMobileRelativePath } from '../files/mobile-file-kind'
|
||||
import { isENOENT } from '../../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../../ipc/filesystem/filesystem-path-containment'
|
||||
import type { RuntimeFileCommandHost } from '../files/file-command-host'
|
||||
import type { RuntimeTerminalArtifacts } from './artifacts/terminal-artifacts'
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ vi.mock('node:fs/promises', () => ({
|
||||
default: { writeFile: fsWriteFileMock, mkdir: fsMkdirMock }
|
||||
}))
|
||||
|
||||
vi.mock('../ipc/filesystem-auth', () => ({
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', () => ({
|
||||
PATH_ACCESS_DENIED_MESSAGE:
|
||||
'Access denied: path resolves outside allowed directories. If this blocks a legitimate workflow, please file a GitHub issue.',
|
||||
resolveAuthorizedPath: resolveAuthorizedPathMock
|
||||
|
||||
@@ -10,9 +10,9 @@ import { randomUUID } from 'node:crypto'
|
||||
import { open, stat } from 'node:fs/promises'
|
||||
import { runProcess } from '@orca/process-host'
|
||||
import type { Store } from '../persistence'
|
||||
import { PATH_ACCESS_DENIED_MESSAGE } from '../ipc/filesystem-auth'
|
||||
import { PATH_ACCESS_DENIED_MESSAGE } from '../ipc/filesystem/filesystem-auth'
|
||||
import { resolveDesktopAuthorizedPath } from '../ipc/local-file-access-resolution'
|
||||
import { isENOENT } from '../ipc/filesystem-path-containment'
|
||||
import { isENOENT } from '../ipc/filesystem/filesystem-path-containment'
|
||||
import {
|
||||
assertClipboardTextWriteWithinLimitWithYield,
|
||||
assertClipboardTextWithinLimitWithYield,
|
||||
|
||||
@@ -40,7 +40,7 @@ vi.mock('node:fs/promises', () => ({
|
||||
writeFile: fsWriteFileMock,
|
||||
default: { writeFile: fsWriteFileMock, mkdir: vi.fn() }
|
||||
}))
|
||||
vi.mock('../ipc/filesystem-auth', () => ({
|
||||
vi.mock('../ipc/filesystem/filesystem-auth', () => ({
|
||||
PATH_ACCESS_DENIED_MESSAGE: 'denied',
|
||||
resolveAuthorizedPath: vi.fn()
|
||||
}))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { isENOENT } from './ipc/filesystem-path-containment'
|
||||
import { isENOENT } from './ipc/filesystem/filesystem-path-containment'
|
||||
import type { GitWorktreeInfo } from '../shared/worktree/types'
|
||||
import type { LocalWorktreeFilesystemOptions } from './local-worktree-filesystem'
|
||||
import { getLocalWorktreePathAccess, toLocalWorktreeRuntimePath } from './local-worktree-filesystem'
|
||||
|
||||
@@ -12,7 +12,7 @@ import { shouldRetryFileLoadError } from '@/components/editor/useEditorPanelFile
|
||||
import { readRuntimeFileContent } from './runtime-file-read-client'
|
||||
import type { RuntimeClientTarget } from '../../../shared/runtime-client-target'
|
||||
|
||||
// Mirrors src/main/ipc/filesystem-auth.ts PATH_ACCESS_DENIED_MESSAGE.
|
||||
// Mirrors src/main/ipc/filesystem/filesystem-auth.ts PATH_ACCESS_DENIED_MESSAGE.
|
||||
const PATH_ACCESS_DENIED_MESSAGE =
|
||||
'Access denied: path resolves outside allowed directories. If this blocks a legitimate workflow, please file a GitHub issue.'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user