0.37.0: download whole folders (recursive) as a .zip from the file browser

The file browser/editor could only download individual files. Add a
recursive directory download that streams the folder as a zip archive,
on the local host and on every remote agent.

- file_service.archive_dir(): zip a directory recursively into a temp
  file, preserving the folder name as the archive root and empty
  subdirectories; symlinks are skipped (no sandbox escape / loops).
- /api/files/download and /agent/files/download branch on directories
  and return application/zip, cleaning up the temp file afterwards.
- Files page: show the download button for folders too (as <name>.zip).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
menzelj
2026-06-21 19:54:50 +00:00
co-authored by Claude Opus 4.8
parent 5bcec06bbd
commit f1782eca0e
6 changed files with 67 additions and 12 deletions
+7
View File
@@ -33,6 +33,7 @@ from fastapi import (
WebSocketDisconnect,
)
from fastapi.responses import FileResponse, JSONResponse
from starlette.background import BackgroundTask
from pydantic import BaseModel
from config import settings
@@ -666,6 +667,12 @@ def files_read(path: str = Query(...)) -> dict:
@app.get("/agent/files/download", dependencies=[Depends(verify_token)])
def files_download(path: str = Query(...)):
if _file_guard(file_service.is_dir, path):
tmp, filename = _file_guard(file_service.archive_dir, path)
return FileResponse(
tmp, filename=filename, media_type="application/zip",
background=BackgroundTask(os.unlink, tmp),
)
real, filename = _file_guard(file_service.resolve_download, path)
return FileResponse(real, filename=filename, media_type="application/octet-stream")