From df529a4a42fd7b23c3d3bc03d3fbd062a912027a Mon Sep 17 00:00:00 2001 From: qiubinbin <767759678@qq.com> Date: Thu, 23 Jul 2026 20:35:49 +0800 Subject: [PATCH 1/2] fix mounted file download URLs --- .../src/features/file-manager/FileManagerPage.tsx | 3 ++- .../file-manager/file-tools/FileActionsMenu.tsx | 3 ++- .../shared/file-surface/FileSurfacePreviewPanel.tsx | 3 ++- tests/system/web-file-manager-domain.test.mjs | 12 ++++++++++++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/web/src/features/file-manager/FileManagerPage.tsx b/apps/web/src/features/file-manager/FileManagerPage.tsx index 39e3cf2c..ca456675 100644 --- a/apps/web/src/features/file-manager/FileManagerPage.tsx +++ b/apps/web/src/features/file-manager/FileManagerPage.tsx @@ -13,6 +13,7 @@ import { useFilesSummaryQuery, } from "@/lib/query/files"; import { toast } from "@/design/ui/sonner"; +import { resolveApiUrl } from "@/lib/runtime"; import { LoadingState } from "@/shared/states/LoadingState"; import { OperationHistoryPanel, @@ -2523,7 +2524,7 @@ function downloadSelectedArchive( const params = new URLSearchParams({ rootId, name: defaultArchiveName() }); for (const selectedPath of selectedPaths) params.append("path", selectedPath); window.open( - `/api/files/download-archive?${params.toString()}`, + resolveApiUrl(`/api/files/download-archive?${params.toString()}`), "_blank", "noopener,noreferrer", ); diff --git a/apps/web/src/features/file-manager/file-tools/FileActionsMenu.tsx b/apps/web/src/features/file-manager/file-tools/FileActionsMenu.tsx index dc9ef29c..bbfdcd3a 100644 --- a/apps/web/src/features/file-manager/file-tools/FileActionsMenu.tsx +++ b/apps/web/src/features/file-manager/file-tools/FileActionsMenu.tsx @@ -28,6 +28,7 @@ import { } from "@/design/ui/dialog"; import { Input } from "@/design/ui/input"; import { dryRunFileTransfer, dryRunUnarchiveFile, transferFiles } from "@/lib/api/files"; +import { resolveApiUrl } from "@/lib/runtime"; import { toast } from "@/design/ui/sonner"; import type { FilesTransferConflictPolicy, @@ -219,7 +220,7 @@ export function FileActionsMenu({ `/api/files/download?rootId=${encodeURIComponent(rootId)}` + `&path=${encodeURIComponent(target.path)}` + `&download=1`; - window.open(url, "_blank", "noopener,noreferrer"); + window.open(resolveApiUrl(url), "_blank", "noopener,noreferrer"); closeAll(); }, [target, rootId, closeAll]); diff --git a/apps/web/src/shared/file-surface/FileSurfacePreviewPanel.tsx b/apps/web/src/shared/file-surface/FileSurfacePreviewPanel.tsx index 8049196d..bdbe4537 100644 --- a/apps/web/src/shared/file-surface/FileSurfacePreviewPanel.tsx +++ b/apps/web/src/shared/file-surface/FileSurfacePreviewPanel.tsx @@ -3,6 +3,7 @@ import * as React from "react"; import { cn } from "@/design/lib/utils"; import { Button } from "@/design/ui/button"; +import { resolveApiUrl } from "@/lib/runtime"; import type { FileEntrySummary, FilesReadPayload } from "../../../../../types/files"; export type FileSurfacePreviewKind = "image" | "video" | "audio" | "pdf" | "binary"; @@ -535,7 +536,7 @@ function PdfPreviewFrame({ src, title }: { src: string; title: string }) { function buildFileDownloadUrl(rootId: string, path: string, attachment = false): string { const search = new URLSearchParams({ rootId, path }); if (attachment) search.set("download", "1"); - return `/api/files/download?${search.toString()}`; + return resolveApiUrl(`/api/files/download?${search.toString()}`); } function previewKindLabel(kind: FileSurfacePreviewKind): string { diff --git a/tests/system/web-file-manager-domain.test.mjs b/tests/system/web-file-manager-domain.test.mjs index 5ca2a8b4..effd6291 100644 --- a/tests/system/web-file-manager-domain.test.mjs +++ b/tests/system/web-file-manager-domain.test.mjs @@ -94,3 +94,15 @@ test("file manager routes files through unified online surface", () => { assert.doesNotMatch(packageJson, /docs:render/); assert.doesNotMatch(packageJson, /markdown-visual-editor|fallback-preview|html-editor|upload-preview|preview-resilience/); }); + +test("file manager direct download URLs honor the mounted API base path", () => { + for (const relativePath of [ + "apps/web/src/shared/file-surface/FileSurfacePreviewPanel.tsx", + "apps/web/src/features/file-manager/file-tools/FileActionsMenu.tsx", + "apps/web/src/features/file-manager/FileManagerPage.tsx", + ]) { + const source = read(relativePath); + assert.match(source, /resolveApiUrl/); + assert.doesNotMatch(source, /window\.open\(\s*`\/api\/files\//); + } +}); From 5b6c43d11c8e3c8934f6a52707789f4a1b158380 Mon Sep 17 00:00:00 2001 From: qiubinbin <767759678@qq.com> Date: Thu, 23 Jul 2026 20:41:01 +0800 Subject: [PATCH 2/2] release v0.2.6 --- apps/api/config.ts | 2 +- apps/api/package.json | 2 +- apps/web/package.json | 2 +- apps/web/vite.config.ts | 2 +- index.html | 2 +- install-tracevane.sh | 2 +- openclaw.plugin.json | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/api/config.ts b/apps/api/config.ts index 9f03c905..c4041172 100644 --- a/apps/api/config.ts +++ b/apps/api/config.ts @@ -10,7 +10,7 @@ const DEFAULT_PORT = 3760; const DEFAULT_GATEWAY_PORT = 31879; const DEFAULT_GATEWAY_BASE_PATH = '/tracevane'; const DEFAULT_BIND_HOST = '127.0.0.1'; -const TRACEVANE_VERSION_FALLBACK = '0.2.4'; +const TRACEVANE_VERSION_FALLBACK = '0.2.6'; let cachedTracevaneVersion: string | null = null; diff --git a/apps/api/package.json b/apps/api/package.json index c314b20e..4265cc1b 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,6 +1,6 @@ { "name": "tracevane-api", - "version": "0.2.4", + "version": "0.2.6", "private": true, "type": "module", "scripts": { diff --git a/apps/web/package.json b/apps/web/package.json index 8e71208c..9ec16838 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "tracevane-web", - "version": "0.2.5", + "version": "0.2.6", "private": true, "type": "module", "scripts": { diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 33305b4f..a2bc90c4 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -27,7 +27,7 @@ const tracevaneBasePath = process.env.TRACEVANE_BASE_PATH || ""; const tracevaneSmokeDisableWatch = process.env.TRACEVANE_SMOKE_DISABLE_WATCH === "1"; const webConfigDir = path.dirname(fileURLToPath(import.meta.url)); const tracevaneRootDir = path.resolve(webConfigDir, "..", ".."); -const TRACEVANE_PACKAGE_VERSION_FALLBACK = "0.2.4"; +const TRACEVANE_PACKAGE_VERSION_FALLBACK = "0.2.6"; const tracevanePackageVersionOverride = process.env.TRACEVANE_BUILD_VERSION?.trim() || ""; const tracevanePackageVersion = (() => { diff --git a/index.html b/index.html index d26c9092..96f7f1d3 100644 --- a/index.html +++ b/index.html @@ -311,7 +311,7 @@