feat(file-panels): panels read and write through a file handle

The file tab stats the file and mounts its panel without reading it. Every
panel, built-in or plugin, gets a PluginFile handle: readText, readBytes, url,
version-checked writeText/writeBytes (PluginFileConflictError unless force),
and watch. useFileText, useFileBytes and useFileUrl read through it, and
Loading joins @getpaseo/plugin/client/ui. Panels own their loading state.

The host document pipeline, the explorer preview cache and the preview
lifecycle are deleted. The daemon classifies a file version from a bounded
sniff and writes base64 content as bytes behind fileByteWrites.

A deleted file keeps its panel mounted; a read confirms the deletion first,
so a remove-and-rewrite is not reported as one. Native Source decodes with
builtins and highlights in idle-time slices, the lines around the opening
line first, so a large file no longer blocks the JS thread.
This commit is contained in:
Mohamed Boudra
2026-10-20 08:02:49 +02:00
parent 970b41cb24
commit dfb6215de0
103 changed files with 3432 additions and 4264 deletions
+8
View File
@@ -2775,6 +2775,10 @@ export const FileVersionSchema = z.discriminatedUnion("status", [
size: z.number().int().nonnegative(),
modifiedAt: z.string(),
revision: z.string().optional(),
// Classified from the extension and the first bytes, so a client can choose how to open the
// file before reading it.
kind: z.enum(["text", "image", "binary"]).optional(),
mimeType: z.string().optional(),
}),
z.object({
status: z.literal("missing"),
@@ -2808,6 +2812,8 @@ export const FileWriteRequestSchema = z.object({
cwd: z.string(),
path: z.string(),
content: z.string(),
// COMPAT(fileByteWrites): added in v0.13.0. Daemons without the feature write `content` as text.
contentEncoding: z.enum(["utf-8", "base64"]).optional(),
expectedModifiedAt: z.string(),
expectedRevision: z.string().optional(),
requestId: z.string(),
@@ -3677,6 +3683,8 @@ export const ServerInfoStatusPayloadSchema = z
workspaceRecovery: z.boolean().optional(),
// COMPAT(workspaceFileEditing): added in v0.2.0, remove after 2027-01-18 once daemon floor >= v0.2.0.
workspaceFileEditing: z.boolean().optional(),
// COMPAT(fileByteWrites): added in v0.13.0, remove gate after 2027-04-20.
fileByteWrites: z.boolean().optional(),
// COMPAT(providerUsageList): added in v0.1.98, drop the gate when daemon floor >= v0.1.98.
providerUsageList: z.boolean().optional(),
// COMPAT(agentDetach): added in v0.1.98, remove gate after 2026-12-19 once daemon floor >= v0.1.98.