fix(desktop): recover from macOS directory permission failures
This commit is contained in:
@@ -13,6 +13,7 @@ import type {
|
||||
FilePartInput,
|
||||
} from "@opencode-ai/sdk/v2";
|
||||
import { isAmbiguousTransportFailure, markAmbiguousTransportFailure } from "@/lib/relay/transport-error";
|
||||
import { FilesystemError, parseFilesystemErrorReason } from "@/lib/api/files-errors";
|
||||
import type { PermissionRequest } from "@/types/permission";
|
||||
import type { QuestionRequest } from "@/types/question";
|
||||
|
||||
@@ -1751,20 +1752,55 @@ class OpencodeService {
|
||||
}
|
||||
|
||||
const task = (async () => {
|
||||
const desktopFiles = getDesktopFilesApi();
|
||||
if (desktopFiles) {
|
||||
const desktopFiles = getDesktopFilesApi();
|
||||
try {
|
||||
const result = await desktopFiles.listDirectory(directoryPath || '', options);
|
||||
if (!result || !Array.isArray(result.entries)) {
|
||||
return [];
|
||||
if (desktopFiles) {
|
||||
const result = await desktopFiles.listDirectory(directoryPath || '', options);
|
||||
if (!result || !Array.isArray(result.entries)) {
|
||||
throw new FilesystemError('Directory listing returned an invalid response', {
|
||||
reason: 'invalid-response',
|
||||
});
|
||||
}
|
||||
const entries = result.entries.map<FilesystemEntry>((entry) => ({
|
||||
name: entry.name,
|
||||
path: normalizeFsPath(entry.path),
|
||||
isDirectory: !!entry.isDirectory,
|
||||
isFile: !entry.isDirectory,
|
||||
isSymbolicLink: false,
|
||||
}));
|
||||
this.listDirectoryCache.set(cacheKey, {
|
||||
entries,
|
||||
expiresAt: Date.now() + FS_LIST_CACHE_TTL_MS,
|
||||
});
|
||||
return entries;
|
||||
}
|
||||
const entries = result.entries.map<FilesystemEntry>((entry) => ({
|
||||
name: entry.name,
|
||||
path: normalizeFsPath(entry.path),
|
||||
isDirectory: !!entry.isDirectory,
|
||||
isFile: !entry.isDirectory,
|
||||
isSymbolicLink: false,
|
||||
}));
|
||||
|
||||
const params = new URLSearchParams();
|
||||
if (directoryPath && directoryPath.trim().length > 0) {
|
||||
params.set('path', directoryPath);
|
||||
}
|
||||
if (options?.respectGitignore) {
|
||||
params.set('respectGitignore', 'true');
|
||||
}
|
||||
const query = params.toString();
|
||||
const response = await runtimeFetch(`${this.baseUrl}/fs/list${query ? `?${query}` : ''}`);
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({}));
|
||||
const message = typeof error.error === 'string' ? error.error : 'Failed to list directory';
|
||||
throw new FilesystemError(message, {
|
||||
reason: parseFilesystemErrorReason((error as { reason?: unknown }).reason),
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
if (!result || !Array.isArray(result.entries)) {
|
||||
throw new FilesystemError('Directory listing returned an invalid response', {
|
||||
reason: 'invalid-response',
|
||||
});
|
||||
}
|
||||
|
||||
const entries = result.entries as FilesystemEntry[];
|
||||
this.listDirectoryCache.set(cacheKey, {
|
||||
entries,
|
||||
expiresAt: Date.now() + FS_LIST_CACHE_TTL_MS,
|
||||
@@ -1774,39 +1810,6 @@ class OpencodeService {
|
||||
console.error('Failed to list directory contents:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const params = new URLSearchParams();
|
||||
if (directoryPath && directoryPath.trim().length > 0) {
|
||||
params.set('path', directoryPath);
|
||||
}
|
||||
if (options?.respectGitignore) {
|
||||
params.set('respectGitignore', 'true');
|
||||
}
|
||||
const query = params.toString();
|
||||
const response = await runtimeFetch(`${this.baseUrl}/fs/list${query ? `?${query}` : ''}`);
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({}));
|
||||
const message = typeof error.error === 'string' ? error.error : 'Failed to list directory';
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
if (!result || !Array.isArray(result.entries)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const entries = result.entries as FilesystemEntry[];
|
||||
this.listDirectoryCache.set(cacheKey, {
|
||||
entries,
|
||||
expiresAt: Date.now() + FS_LIST_CACHE_TTL_MS,
|
||||
});
|
||||
return entries;
|
||||
} catch (error) {
|
||||
console.error('Failed to list directory contents:', error);
|
||||
throw error;
|
||||
}
|
||||
})();
|
||||
|
||||
const trackedTask = task.finally(() => {
|
||||
|
||||
Reference in New Issue
Block a user