v0.26.0
filex v0.26.0
Self-hosted file manager — Go single binary + multi-framework frontend.
Download a binary below, or pull a Docker image:
docker pull ghcr.io/brf-tech/filex:slim-v0.26.0
docker pull ghcr.io/brf-tech/filex:full-v0.26.0What changed
Added
-
Upload tickets: an agent can finally upload a large local file. Every
agent-facing write surface carried its bytes inside the call —/api/ai/upload's
JSON body, the MCPfile_writetool — and on an MCP transport that means through
the model's context. A 130 MB file is ~173 MB of base64 there: not slow,
impossible. The agent was left telling its user "I can't upload this" (one
spreadsheet cost an hour on 2026-08-27).POST /api/ai/upload/ticket(scopewrite) now splits the job in two. The
authorized half resolves and pins the destination under the caller's own
token — confinement root, tenant scope and editor grant all checked there, and a
folder as the destination is refused before a byte moves. The transfer half is a
plainPUT/POSTto/u/{ticket}that needs no credentials at all, so
an agent with no filex token (a Coder workspace, a fleet agent) can finish the
upload with the ready-madecurl -T <file> <url>line the mint call returns.The URL is not a key to filex, it is a key to one write: single-use, minutes
long by default (30 min, max 24 h), no read/list/delete, and the redeemer cannot
name a path. The bytes are written as — and billed to — the minter, and land on
the same staging/thumbnail/write-hook path as any other upload. Refusals are
distinct and non-guessy:404unknown or already redeemed (the same answer on
purpose),410expired,409in flight,411noContent-Length,413over
the ticket ceiling (the ticket survives, so a corrected upload still works), and
503 storage_unavailable/507 quota_exceededwhen the backend is the problem.Also exposed as the MCP tool
file_upload_ticket, andfile_write's
description now sends anything already on disk there instead of to base64.