docs: plan binary browser attachments
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# Binary File Write And Browser Attachments Design
|
||||
|
||||
## Purpose
|
||||
|
||||
Browser Inbox still cannot complete binary file attachment conversion because
|
||||
the public Files API can read bounded bytes but cannot write them. This slice
|
||||
adds a bounded public `files.writeBytes` contract and uses it to convert browser
|
||||
file captures that contain base64 data.
|
||||
|
||||
The goal is not streaming or large-file import. It is a safe, testable binary
|
||||
write path for small attachments that keeps plugins on public APIs.
|
||||
|
||||
## Scope
|
||||
|
||||
This slice adds:
|
||||
|
||||
- `api.files.writeBytes(relativePath, dataBase64, options)` for enabled plugins
|
||||
with `files.write`;
|
||||
- desktop service support for atomic bounded byte writes up to 8 MB;
|
||||
- sync op payload support for `dataBase64`, while preserving older text
|
||||
`content` payloads;
|
||||
- SDK type/mock/test coverage for `files.writeBytes`;
|
||||
- browser extension file capture that sends `file.dataBase64` for all selected
|
||||
files up to 8 MB and keeps `file.text` only for text-compatible files;
|
||||
- local receiver flattening of `fileDataBase64`;
|
||||
- Browser Inbox conversion that prefers `api.files.writeBytes` when binary data
|
||||
is present and falls back to `api.files.writeText` for text-only captures.
|
||||
|
||||
It does not add chunked streaming, folders, drag-and-drop from pages, download
|
||||
interception, or binary preview changes.
|
||||
|
||||
## Files API Contract
|
||||
|
||||
`files.writeBytes(relativePath, dataBase64, options)`:
|
||||
|
||||
- accepts canonical vault-relative slash paths;
|
||||
- rejects traversal, absolute paths, `.verstak`, symlinks, folders, missing
|
||||
parents, and conflicts using the same path policy as `writeText`;
|
||||
- rejects invalid base64;
|
||||
- rejects decoded payloads over `MaxBinaryReadBytes` (8 MB);
|
||||
- writes atomically through a temp file in the target directory;
|
||||
- requires `files.write`;
|
||||
- records the same `file.changed` activity shape as text writes;
|
||||
- records sync create/update payloads as `{ "path": "...", "dataBase64": "..." }`.
|
||||
|
||||
Remote sync apply supports both:
|
||||
|
||||
- old text payloads: `{ "path": "...", "content": "..." }`;
|
||||
- new byte payloads: `{ "path": "...", "dataBase64": "..." }`.
|
||||
|
||||
## Browser Capture Contract
|
||||
|
||||
For `kind: "file"`, the extension sends:
|
||||
|
||||
```json
|
||||
{
|
||||
"file": {
|
||||
"name": "photo.png",
|
||||
"mime": "image/png",
|
||||
"size": 1234,
|
||||
"dataBase64": "iVBORw0KGgo...",
|
||||
"text": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`file.name` is required. A file capture is valid when either `file.dataBase64`
|
||||
or `file.text` is present. The extension rejects selected files over 8 MB before
|
||||
sending.
|
||||
|
||||
## Browser Inbox Conversion
|
||||
|
||||
Browser Inbox stores both `fileText` and `fileDataBase64`. `Create File` writes:
|
||||
|
||||
- `api.files.writeBytes(path, fileDataBase64, { createIfMissing: true,
|
||||
overwrite: false })` when binary data is present;
|
||||
- otherwise `api.files.writeText(path, fileText, { createIfMissing: true,
|
||||
overwrite: false })`.
|
||||
|
||||
On success it publishes `browser.capture.converted` with
|
||||
`conversionType: "file"` and removes the capture. On write failure it leaves the
|
||||
capture in the queue and renders an error.
|
||||
|
||||
## Testing
|
||||
|
||||
Required checks:
|
||||
|
||||
- core Files service writes bytes, rejects invalid/oversized payloads, and
|
||||
preserves conflict/path behavior;
|
||||
- desktop API bridge enforces `files.write`, records sync `dataBase64`, and
|
||||
applies remote binary payloads;
|
||||
- frontend plugin API exposes `files.writeBytes`;
|
||||
- SDK types and mock API include `writeBytes`;
|
||||
- browser extension protocol builds, validates, and queues binary captures;
|
||||
- receiver accepts file captures with `dataBase64`;
|
||||
- Browser Inbox smoke proves binary conversion uses `writeBytes`;
|
||||
- full verification scripts pass for touched repos.
|
||||
Reference in New Issue
Block a user