放开部分文件读/写限制
This commit is contained in:
@@ -777,10 +777,9 @@ export function FileWorkspacePanel() {
|
|||||||
const renderedContent = activeFileTab?.content ?? ""
|
const renderedContent = activeFileTab?.content ?? ""
|
||||||
const isFileTab = activeFileTab?.kind === "file"
|
const isFileTab = activeFileTab?.kind === "file"
|
||||||
const fileReadonly = isFileTab ? Boolean(activeFileTab.readonly) : true
|
const fileReadonly = isFileTab ? Boolean(activeFileTab.readonly) : true
|
||||||
const fileTruncated = isFileTab ? Boolean(activeFileTab.truncated) : false
|
|
||||||
const fileSaveState = isFileTab ? (activeFileTab.saveState ?? "idle") : "idle"
|
const fileSaveState = isFileTab ? (activeFileTab.saveState ?? "idle") : "idle"
|
||||||
const fileIsDirty = isFileTab ? Boolean(activeFileTab.isDirty) : false
|
const fileIsDirty = isFileTab ? Boolean(activeFileTab.isDirty) : false
|
||||||
const canEdit = isFileTab && !fileReadonly && !fileTruncated
|
const canEdit = isFileTab && !fileReadonly
|
||||||
const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
const autoSaveGuardRef = useRef({
|
const autoSaveGuardRef = useRef({
|
||||||
canEdit: false,
|
canEdit: false,
|
||||||
|
|||||||
@@ -2302,7 +2302,9 @@ export function FileTreeTab() {
|
|||||||
<DialogContent
|
<DialogContent
|
||||||
onOpenAutoFocus={(e) => {
|
onOpenAutoFocus={(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const input = (e.currentTarget as HTMLElement | null)?.querySelector("input")
|
const input = (
|
||||||
|
e.currentTarget as HTMLElement | null
|
||||||
|
)?.querySelector("input")
|
||||||
if (input) requestAnimationFrame(() => input.focus())
|
if (input) requestAnimationFrame(() => input.focus())
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -2369,7 +2371,9 @@ export function FileTreeTab() {
|
|||||||
<DialogContent
|
<DialogContent
|
||||||
onOpenAutoFocus={(e) => {
|
onOpenAutoFocus={(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const input = (e.currentTarget as HTMLElement | null)?.querySelector("input")
|
const input = (
|
||||||
|
e.currentTarget as HTMLElement | null
|
||||||
|
)?.querySelector("input")
|
||||||
if (input) requestAnimationFrame(() => input.focus())
|
if (input) requestAnimationFrame(() => input.focus())
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2040,10 +2040,7 @@ function hasComparableVersion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildVersionCheck(agent: AcpAgentInfo): UiCheckItem | null {
|
function buildVersionCheck(agent: AcpAgentInfo): UiCheckItem | null {
|
||||||
if (
|
if (agent.distribution_type !== "binary" && agent.distribution_type !== "npx")
|
||||||
agent.distribution_type !== "binary" &&
|
|
||||||
agent.distribution_type !== "npx"
|
|
||||||
)
|
|
||||||
return null
|
return null
|
||||||
|
|
||||||
const remoteVersion = agent.registry_version ?? "unknown"
|
const remoteVersion = agent.registry_version ?? "unknown"
|
||||||
@@ -2390,46 +2387,51 @@ export function AcpAgentSettings() {
|
|||||||
|
|
||||||
const runPreflight = useCallback(
|
const runPreflight = useCallback(
|
||||||
async (agentType: AgentType, forceRefresh?: boolean) => {
|
async (agentType: AgentType, forceRefresh?: boolean) => {
|
||||||
setChecking((prev) => ({ ...prev, [agentType]: true }))
|
setChecking((prev) => ({ ...prev, [agentType]: true }))
|
||||||
try {
|
try {
|
||||||
const [resultState, versionState] = await Promise.allSettled([
|
const [resultState, versionState] = await Promise.allSettled([
|
||||||
acpPreflight(agentType, forceRefresh),
|
acpPreflight(agentType, forceRefresh),
|
||||||
acpDetectAgentLocalVersion(agentType),
|
acpDetectAgentLocalVersion(agentType),
|
||||||
])
|
])
|
||||||
|
|
||||||
if (versionState.status === "fulfilled") {
|
if (versionState.status === "fulfilled") {
|
||||||
setAgents((prev) => {
|
setAgents((prev) => {
|
||||||
if (versionState.value === null) return prev
|
if (versionState.value === null) return prev
|
||||||
let changed = false
|
let changed = false
|
||||||
const next = prev.map((agent) => {
|
const next = prev.map((agent) => {
|
||||||
if (agent.agent_type !== agentType) return agent
|
if (agent.agent_type !== agentType) return agent
|
||||||
if (agent.installed_version === versionState.value) return agent
|
if (agent.installed_version === versionState.value) return agent
|
||||||
changed = true
|
changed = true
|
||||||
return { ...agent, installed_version: versionState.value }
|
return { ...agent, installed_version: versionState.value }
|
||||||
|
})
|
||||||
|
return changed ? next : prev
|
||||||
})
|
})
|
||||||
return changed ? next : prev
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resultState.status === "fulfilled") {
|
if (resultState.status === "fulfilled") {
|
||||||
setCheckState((prev) => ({
|
setCheckState((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[agentType]: { result: resultState.value },
|
[agentType]: { result: resultState.value },
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
const message =
|
const message =
|
||||||
resultState.reason instanceof Error
|
resultState.reason instanceof Error
|
||||||
? resultState.reason.message
|
? resultState.reason.message
|
||||||
: String(resultState.reason)
|
: String(resultState.reason)
|
||||||
|
setCheckState((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[agentType]: { error: message },
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
const message = err instanceof Error ? err.message : String(err)
|
||||||
setCheckState((prev) => ({ ...prev, [agentType]: { error: message } }))
|
setCheckState((prev) => ({ ...prev, [agentType]: { error: message } }))
|
||||||
|
} finally {
|
||||||
|
setChecking((prev) => ({ ...prev, [agentType]: false }))
|
||||||
}
|
}
|
||||||
} catch (err) {
|
},
|
||||||
const message = err instanceof Error ? err.message : String(err)
|
[]
|
||||||
setCheckState((prev) => ({ ...prev, [agentType]: { error: message } }))
|
)
|
||||||
} finally {
|
|
||||||
setChecking((prev) => ({ ...prev, [agentType]: false }))
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const runAllPreflight = useCallback(
|
const runAllPreflight = useCallback(
|
||||||
async (agentTypes: AgentType[]) => {
|
async (agentTypes: AgentType[]) => {
|
||||||
@@ -2790,10 +2792,7 @@ export function AcpAgentSettings() {
|
|||||||
await runNpxAction(agent, "upgrade")
|
await runNpxAction(agent, "upgrade")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (action.kind === "uninstall_binary" || action.kind === "uninstall_npx") {
|
||||||
action.kind === "uninstall_binary" ||
|
|
||||||
action.kind === "uninstall_npx"
|
|
||||||
) {
|
|
||||||
setUninstallConfirmAgent(agent)
|
setUninstallConfirmAgent(agent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ export interface FileWorkspaceTab {
|
|||||||
etag?: string | null
|
etag?: string | null
|
||||||
mtimeMs?: number | null
|
mtimeMs?: number | null
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
truncated?: boolean
|
|
||||||
lineEnding?: LineEnding
|
lineEnding?: LineEnding
|
||||||
saveState?: FileSaveState
|
saveState?: FileSaveState
|
||||||
saveError?: string | null
|
saveError?: string | null
|
||||||
@@ -150,7 +149,6 @@ function loadingTab(
|
|||||||
etag: null,
|
etag: null,
|
||||||
mtimeMs: null,
|
mtimeMs: null,
|
||||||
readonly: kind !== "file",
|
readonly: kind !== "file",
|
||||||
truncated: false,
|
|
||||||
lineEnding: "none",
|
lineEnding: "none",
|
||||||
saveState: "idle",
|
saveState: "idle",
|
||||||
saveError: null,
|
saveError: null,
|
||||||
@@ -390,7 +388,6 @@ export function WorkspaceProvider({ children }: WorkspaceProviderProps) {
|
|||||||
etag: result.etag,
|
etag: result.etag,
|
||||||
mtimeMs: result.mtime_ms,
|
mtimeMs: result.mtime_ms,
|
||||||
readonly: result.readonly,
|
readonly: result.readonly,
|
||||||
truncated: result.truncated,
|
|
||||||
lineEnding: result.line_ending,
|
lineEnding: result.line_ending,
|
||||||
saveState: "idle",
|
saveState: "idle",
|
||||||
saveError: null,
|
saveError: null,
|
||||||
@@ -512,7 +509,6 @@ export function WorkspaceProvider({ children }: WorkspaceProviderProps) {
|
|||||||
gitShowFile(folderPath, path).catch(() => ""),
|
gitShowFile(folderPath, path).catch(() => ""),
|
||||||
readFilePreview(folderPath, path).catch(() => ({
|
readFilePreview(folderPath, path).catch(() => ({
|
||||||
content: "",
|
content: "",
|
||||||
truncated: false,
|
|
||||||
path: "",
|
path: "",
|
||||||
})),
|
})),
|
||||||
]),
|
]),
|
||||||
@@ -564,7 +560,6 @@ export function WorkspaceProvider({ children }: WorkspaceProviderProps) {
|
|||||||
gitShowFile(folderPath, path, targetBranch).catch(() => ""),
|
gitShowFile(folderPath, path, targetBranch).catch(() => ""),
|
||||||
readFilePreview(folderPath, path).catch(() => ({
|
readFilePreview(folderPath, path).catch(() => ({
|
||||||
content: "",
|
content: "",
|
||||||
truncated: false,
|
|
||||||
path: "",
|
path: "",
|
||||||
})),
|
})),
|
||||||
]),
|
]),
|
||||||
@@ -715,7 +710,7 @@ export function WorkspaceProvider({ children }: WorkspaceProviderProps) {
|
|||||||
setFileTabs((prev) =>
|
setFileTabs((prev) =>
|
||||||
prev.map((tab) => {
|
prev.map((tab) => {
|
||||||
if (tab.id !== activeFileTabId || tab.kind !== "file") return tab
|
if (tab.id !== activeFileTabId || tab.kind !== "file") return tab
|
||||||
if (tab.loading || tab.readonly || tab.truncated) return tab
|
if (tab.loading || tab.readonly) return tab
|
||||||
if (tab.content === content) return tab
|
if (tab.content === content) return tab
|
||||||
|
|
||||||
const savedContent = tab.savedContent ?? ""
|
const savedContent = tab.savedContent ?? ""
|
||||||
@@ -739,7 +734,7 @@ export function WorkspaceProvider({ children }: WorkspaceProviderProps) {
|
|||||||
(candidate) => candidate.id === tabId
|
(candidate) => candidate.id === tabId
|
||||||
)
|
)
|
||||||
if (!tab || tab.kind !== "file") return false
|
if (!tab || tab.kind !== "file") return false
|
||||||
if (tab.loading || tab.readonly || tab.truncated) return false
|
if (tab.loading || tab.readonly) return false
|
||||||
if (!tab.path) return false
|
if (!tab.path) return false
|
||||||
if (!tab.isDirty) return true
|
if (!tab.isDirty) return true
|
||||||
|
|
||||||
@@ -868,7 +863,6 @@ export function WorkspaceProvider({ children }: WorkspaceProviderProps) {
|
|||||||
etag: result.etag,
|
etag: result.etag,
|
||||||
mtimeMs: result.mtime_ms,
|
mtimeMs: result.mtime_ms,
|
||||||
readonly: result.readonly,
|
readonly: result.readonly,
|
||||||
truncated: result.truncated,
|
|
||||||
lineEnding: result.line_ending,
|
lineEnding: result.line_ending,
|
||||||
saveState: "idle",
|
saveState: "idle",
|
||||||
saveError: null,
|
saveError: null,
|
||||||
|
|||||||
@@ -900,26 +900,16 @@ export async function readFileBase64(
|
|||||||
|
|
||||||
export async function readFilePreview(
|
export async function readFilePreview(
|
||||||
rootPath: string,
|
rootPath: string,
|
||||||
path: string,
|
path: string
|
||||||
maxBytes?: number
|
|
||||||
): Promise<FilePreviewContent> {
|
): Promise<FilePreviewContent> {
|
||||||
return invoke("read_file_preview", {
|
return invoke("read_file_preview", { rootPath, path })
|
||||||
rootPath,
|
|
||||||
path,
|
|
||||||
maxBytes: maxBytes ?? null,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function readFileForEdit(
|
export async function readFileForEdit(
|
||||||
rootPath: string,
|
rootPath: string,
|
||||||
path: string,
|
path: string
|
||||||
maxBytes?: number
|
|
||||||
): Promise<FileEditContent> {
|
): Promise<FileEditContent> {
|
||||||
return invoke("read_file_for_edit", {
|
return invoke("read_file_for_edit", { rootPath, path })
|
||||||
rootPath,
|
|
||||||
path,
|
|
||||||
maxBytes: maxBytes ?? null,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveFileContent(
|
export async function saveFileContent(
|
||||||
|
|||||||
@@ -677,7 +677,6 @@ export type FileTreeNode =
|
|||||||
export interface FilePreviewContent {
|
export interface FilePreviewContent {
|
||||||
path: string
|
path: string
|
||||||
content: string
|
content: string
|
||||||
truncated: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileEditContent {
|
export interface FileEditContent {
|
||||||
@@ -686,7 +685,6 @@ export interface FileEditContent {
|
|||||||
etag: string
|
etag: string
|
||||||
mtime_ms: number | null
|
mtime_ms: number | null
|
||||||
readonly: boolean
|
readonly: boolean
|
||||||
truncated: boolean
|
|
||||||
line_ending: "lf" | "crlf" | "mixed" | "none"
|
line_ending: "lf" | "crlf" | "mixed" | "none"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user