mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 02:59:35 +00:00
feat: webUI 文本文件编辑/保存 + 相关改动
- FileViewer 新增文本编辑模式(textarea + 保存/取消 + Ctrl+S) - 后端 /api/files POST 新增 type=write 原子写入 - i18n 补充编辑相关文案(en/zh-CN) - searxng-search: 加强 web_search 自动搜索条件 - worktree/next.config: 路径比较与 allowedDevOrigins 优化
This commit is contained in:
@@ -304,6 +304,16 @@ export const enLocale: LocalePlugin = {
|
||||
"i18n.mentionSelectedLines": "Mention selected lines",
|
||||
"i18n.disableWrap": "Disable word wrap",
|
||||
"i18n.enableWrap": "Enable word wrap",
|
||||
"i18n.editFile": "Edit file",
|
||||
"i18n.stopEditing": "Stop editing",
|
||||
"i18n.saveFile": "Save file",
|
||||
"i18n.saveShortcut": "Save (Ctrl/Cmd+S)",
|
||||
"i18n.discardChanges": "Discard unsaved changes",
|
||||
"i18n.saveError": "Could not save file: {error}",
|
||||
"i18n.closeWithoutSaving": "You have unsaved changes. Discard them and exit editing?",
|
||||
"i18n.editing": "Editing",
|
||||
"i18n.unsaved": "unsaved changes",
|
||||
"i18n.readOnly": "Read-only",
|
||||
"i18n.htmlPreview": "HTML preview",
|
||||
"i18n.previewFile": "Preview {file}",
|
||||
"i18n.invalidMermaid": "Invalid Mermaid diagram",
|
||||
|
||||
@@ -304,6 +304,16 @@ export const zhCNLocale: LocalePlugin = {
|
||||
"i18n.mentionSelectedLines": "提及所选行",
|
||||
"i18n.disableWrap": "禁用自动换行",
|
||||
"i18n.enableWrap": "启用自动换行",
|
||||
"i18n.editFile": "编辑文件",
|
||||
"i18n.stopEditing": "停止编辑",
|
||||
"i18n.saveFile": "保存文件",
|
||||
"i18n.saveShortcut": "保存(Ctrl/Cmd+S)",
|
||||
"i18n.discardChanges": "放弃未保存的更改",
|
||||
"i18n.saveError": "无法保存文件:{error}",
|
||||
"i18n.closeWithoutSaving": "您有未保存的更改。放弃并退出编辑?",
|
||||
"i18n.editing": "编辑中",
|
||||
"i18n.unsaved": "未保存的更改",
|
||||
"i18n.readOnly": "只读",
|
||||
"i18n.htmlPreview": "HTML 预览",
|
||||
"i18n.previewFile": "预览 {file}",
|
||||
"i18n.invalidMermaid": "Mermaid 图表无效",
|
||||
|
||||
+11
-2
@@ -2,7 +2,7 @@ import { execFile } from "child_process";
|
||||
import { existsSync, mkdirSync, realpathSync } from "fs";
|
||||
import { basename, dirname, join, resolve } from "path";
|
||||
import { promisify } from "util";
|
||||
import { allowFileRoot } from "./allowed-roots";
|
||||
import { allowFileRoot, normalizeSlashes } from "./allowed-roots";
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
@@ -48,6 +48,15 @@ export function invalidateProjectCache(): void {
|
||||
globalThis.__piProjectCache?.clear();
|
||||
}
|
||||
|
||||
/** Path equality that tolerates Windows quirks: git prints forward slashes
|
||||
* while realpathSync uses backslashes, and drive letters may differ in case. */
|
||||
function samePath(a: string, b: string): boolean {
|
||||
if (process.platform === "win32") {
|
||||
return normalizeSlashes(a).toLowerCase() === normalizeSlashes(b).toLowerCase();
|
||||
}
|
||||
return a === b;
|
||||
}
|
||||
|
||||
async function git(cwd: string, args: string[]): Promise<string> {
|
||||
const { stdout } = await execFileAsync("git", ["-C", cwd, ...args], {
|
||||
timeout: 10_000,
|
||||
@@ -99,7 +108,7 @@ export async function resolveProject(cwd: string): Promise<ProjectInfo> {
|
||||
// cwd is a subdirectory of a repo keeps its own project identity —
|
||||
// grouping subdirs under the repo root would change where new sessions
|
||||
// are created for existing users.
|
||||
const isTopLevel = toplevel === realCwd;
|
||||
const isTopLevel = samePath(toplevel, realCwd);
|
||||
const isWorktreeTopLevel = gitDir !== commonDir && isTopLevel;
|
||||
info = {
|
||||
projectRoot: isWorktreeTopLevel ? dirname(commonDir) : cwd,
|
||||
|
||||
Reference in New Issue
Block a user