docs: plan browser inbox text file attachments

This commit is contained in:
mirivlad 2026-06-29 09:57:21 +08:00
parent bd7558d2f9
commit 5be14d5ec0
4 changed files with 294 additions and 6 deletions

View File

@ -160,6 +160,8 @@ case.selected
browser.capture.page browser.capture.page
browser.capture.selection browser.capture.selection
browser.capture.link browser.capture.link
browser.capture.file
browser.capture.converted
``` ```
Текущий статус: базовый `verstak.activity` implemented as both a global sidebar Текущий статус: базовый `verstak.activity` implemented as both a global sidebar
@ -255,8 +257,9 @@ exact domain match into the bound workspace queue. Its first conversion workflow
creates ordinary Markdown notes through the public Files API and publishes a creates ordinary Markdown notes through the public Files API and publishes a
`browser.capture.converted` event, which Activity records through its public `browser.capture.converted` event, which Activity records through its public
provider subscription. Browser Inbox also creates human-readable `.url` link provider subscription. Browser Inbox also creates human-readable `.url` link
files through the public Files API. File attachment capture/conversion is still files through the public Files API. It now accepts selected text files from the
future work. browser extension and creates ordinary workspace files through the public Files
API. Binary attachment capture/conversion remains future work.
## 9. `official.search` ## 9. `official.search`

View File

@ -57,8 +57,9 @@ Known remaining gaps:
- Browser extension repository has protocol, queue, and Chromium/Firefox build - Browser extension repository has protocol, queue, and Chromium/Firefox build
scaffold; desktop has a local receiver and mounted-view inbox plugin; receiver scaffold; desktop has a local receiver and mounted-view inbox plugin; receiver
pairing, basic Browser Inbox domain binding, create-note conversion, and pairing, basic Browser Inbox domain binding, create-note conversion, and
create-link conversion are implemented, and Activity records conversions. create-link conversion are implemented, text file attachment conversion is
File attachment capture/conversion remains future work. implemented, and Activity records conversions. Binary attachment
capture/conversion remains future work.
- Packaging/update/release workflow is not product-grade yet. - Packaging/update/release workflow is not product-grade yet.
## 4. Implementation Phases ## 4. Implementation Phases
@ -169,7 +170,8 @@ Tasks:
- [x] convert inbox entries into notes through public plugin APIs; - [x] convert inbox entries into notes through public plugin APIs;
- [x] record converted inbox entries in Activity through public plugin events; - [x] record converted inbox entries in Activity through public plugin events;
- [x] convert inbox entries into link files through public plugin APIs; - [x] convert inbox entries into link files through public plugin APIs;
- convert captured file attachments through public - [x] convert captured text file attachments through public plugin APIs;
- convert captured binary attachments through public
plugin APIs. plugin APIs.
Verification: Verification:
@ -240,7 +242,7 @@ Verification:
4. [x] Notes trash/delete UX in `verstak-official-plugins`. 4. [x] Notes trash/delete UX in `verstak-official-plugins`.
5. [x] Sync hardening pass with expanded real two-vault smoke. 5. [x] Sync hardening pass with expanded real two-vault smoke.
6. [~] Browser inbox protocol design, extension scaffold, local receiver, and 6. [~] Browser inbox protocol design, extension scaffold, local receiver, and
minimal inbox plugin are implemented; file attachment conversion remains. minimal inbox plugin are implemented; binary attachment conversion remains.
This order finishes generic platform surfaces before building product features This order finishes generic platform surfaces before building product features
that depend on them. that depend on them.

View File

@ -0,0 +1,171 @@
# Browser Inbox Text File Attachment Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add end-to-end text file attachment capture and conversion through Browser Inbox.
**Architecture:** The browser extension remains a protocol producer and does not know workspace internals. Desktop receiver validates and republishes `browser.capture.file`; Browser Inbox stores the capture and writes the final text file through the public Files API.
**Tech Stack:** Plain JavaScript WebExtension code, Go receiver tests, official plugin JavaScript smoke harness, Markdown docs.
## Global Constraints
- Do not add private `.verstak/inbox` staging in this slice.
- Do not add binary file writes in this slice.
- Use only existing public plugin APIs for conversion: `api.files.writeText` and `api.events.publish`.
- Keep the extension offline queue behavior unchanged.
- Use TDD for each behavior change.
---
### Task 1: Extension Text File Capture Protocol
**Files:**
- Modify: `/home/mirivlad/git/verstak2/verstak-browser-extension/shared/protocol.js`
- Modify: `/home/mirivlad/git/verstak2/verstak-browser-extension/shared/background.js`
- Modify: `/home/mirivlad/git/verstak2/verstak-browser-extension/shared/popup/popup.html`
- Modify: `/home/mirivlad/git/verstak2/verstak-browser-extension/shared/popup/popup.css`
- Modify: `/home/mirivlad/git/verstak2/verstak-browser-extension/shared/popup/popup.js`
- Modify: `/home/mirivlad/git/verstak2/verstak-browser-extension/scripts/test-protocol.js`
- Modify: `/home/mirivlad/git/verstak2/verstak-browser-extension/README.md`
**Interfaces:**
- Produces `kind: "file"` capture payloads with `file.name`, `file.mime`,
`file.size`, and `file.text`.
- [ ] **Step 1: Write RED protocol assertions**
Add a test that builds a file capture and asserts `validateCapture` accepts it,
then add a validation rejection for missing `file.text`.
- [ ] **Step 2: Run RED**
```bash
cd /home/mirivlad/git/verstak2/verstak-browser-extension
PATH=/tmp/verstak2-tools:/home/mirivlad/.lmstudio/.internal/utils:$PATH npm test
```
Expected: failure mentioning unsupported `kind` or missing file validation.
- [ ] **Step 3: Implement protocol and popup capture**
Add `file` payload support in `buildCapture` / `validateCapture`. Add a popup
file input and `Send File` button that reads one selected file as text and sends
`{ type: "verstak.capture", kind: "file", fileName, fileMime, fileSize, fileText }`.
- [ ] **Step 4: Run GREEN**
```bash
PATH=/tmp/verstak2-tools:/home/mirivlad/.lmstudio/.internal/utils:$PATH npm test
PATH=/tmp/verstak2-tools:/home/mirivlad/.lmstudio/.internal/utils:$PATH npm run build
```
Expected: protocol tests pass and extension dist builds.
### Task 2: Desktop Receiver File Event
**Files:**
- Modify: `/home/mirivlad/git/verstak2/verstak-desktop-current/internal/core/browserreceiver/receiver.go`
- Modify: `/home/mirivlad/git/verstak2/verstak-desktop-current/internal/core/browserreceiver/receiver_test.go`
**Interfaces:**
- Consumes extension `kind: "file"` payloads.
- Produces `browser.capture.file` events with flattened `fileName`,
`fileMime`, `fileSize`, and `fileText`.
- [ ] **Step 1: Write RED receiver test**
Add a test that subscribes to `browser.capture.file`, posts a file capture, and
asserts the flattened event payload.
- [ ] **Step 2: Run RED**
```bash
cd /home/mirivlad/git/verstak2/verstak-desktop-current
go test ./internal/core/browserreceiver -run TestReceiverAcceptsFileCaptureAndPublishesEvent -count=1
```
Expected: failure with unsupported kind.
- [ ] **Step 3: Implement receiver support**
Add a `CaptureFile` struct, `File *CaptureFile` field, file validation, and
file payload flattening in `EventPayload`.
- [ ] **Step 4: Run GREEN**
```bash
go test ./internal/core/browserreceiver
./scripts/test.sh
```
Expected: receiver package and desktop script pass.
### Task 3: Browser Inbox Create File Conversion
**Files:**
- Modify: `/home/mirivlad/git/verstak2/verstak-official-plugins/plugins/browser-inbox/frontend/src/index.js`
- Modify: `/home/mirivlad/git/verstak2/verstak-official-plugins/scripts/smoke-browser-inbox-plugin.js`
**Interfaces:**
- Consumes `browser.capture.file` events.
- Produces `Create File` action and `browser.capture.converted` with
`conversionType: "file"`.
- [ ] **Step 1: Write RED smoke test**
Add success and failure scenarios for a workspace file capture. Assert the write
path `Project/Files/notes.txt`, file content, write options, queue removal, and
converted event.
- [ ] **Step 2: Run RED**
```bash
cd /home/mirivlad/git/verstak2/verstak-official-plugins
PATH=/tmp/verstak2-tools:/home/mirivlad/.lmstudio/.internal/utils:$PATH node scripts/smoke-browser-inbox-plugin.js
```
Expected: failure because `browser.capture.file` is not subscribed or
`Create File` is not rendered.
- [ ] **Step 3: Implement conversion**
Preserve `fileName`, `fileMime`, `fileSize`, and `fileText` in storage. Render a
`Create File` button for workspace file captures with text content. Write the
safe file path through `api.files.writeText`, publish the converted event, and
remove the capture on success.
- [ ] **Step 4: Run GREEN**
```bash
PATH=/tmp/verstak2-tools:/home/mirivlad/.lmstudio/.internal/utils:$PATH node scripts/smoke-browser-inbox-plugin.js
PATH=/tmp/verstak2-tools/venv/bin:/tmp/verstak2-tools:/home/mirivlad/.lmstudio/.internal/utils:$PATH ./scripts/check.sh
```
Expected: browser inbox smoke and official plugin check pass.
### Task 4: Roadmap Documentation
**Files:**
- Modify: `/home/mirivlad/git/verstak2/verstak-docs/05_Official_Plugins.md`
- Modify: `/home/mirivlad/git/verstak2/verstak-docs/07_Full_Implementation_Roadmap.md`
**Interfaces:**
- Consumes verified file capture/conversion behavior.
- Produces roadmap language that marks text file attachment conversion complete
while leaving binary attachments for a future public API slice.
- [ ] **Step 1: Update docs**
Describe Browser Inbox text file capture and conversion through the public Files
API.
- [ ] **Step 2: Verify docs**
```bash
cd /home/mirivlad/git/verstak2/verstak-docs
git diff --check
rg -n "text file attachment|binary attachment|browser.capture.file|Create File" 05_Official_Plugins.md 07_Full_Implementation_Roadmap.md docs/superpowers/specs/2026-06-29-browser-inbox-text-file-attachment-design.md docs/superpowers/plans/2026-06-29-browser-inbox-text-file-attachment.md
```
Expected: whitespace check exits 0 and `rg` shows updated status lines.

View File

@ -0,0 +1,112 @@
# Browser Inbox Text File Attachment Design
## Purpose
Browser Inbox needs a first file attachment path that uses the current public
plugin API instead of adding a private core inbox or binary write shortcut. This
slice supports text file attachments end to end: the browser extension reads a
user-selected text file, the local receiver publishes a `browser.capture.file`
event, and Browser Inbox converts the capture into an ordinary workspace file
through `api.files.writeText`.
Binary attachments remain out of scope until the platform has an explicit
public binary write API.
## Scope
This slice adds:
- extension protocol support for `kind: "file"`;
- popup file selection for text files;
- local receiver validation and event publication for file captures;
- Browser Inbox storage/rendering of file metadata and text content;
- a `Create File` conversion action for workspace-scoped text file captures.
It does not add drag-and-drop from web pages, screenshot capture, native download
interception, binary files, folders, or a core `.verstak/inbox` staging area.
## Capture Contract
The extension sends schema version 1 with a new file object:
```json
{
"schemaVersion": 1,
"captureId": "generated-id",
"capturedAt": "2026-06-29T00:00:00.000Z",
"source": "verstak-browser-extension",
"kind": "file",
"page": {
"url": "https://example.com/current-page",
"title": "Current page",
"domain": "example.com"
},
"file": {
"name": "notes.txt",
"mime": "text/plain",
"size": 120,
"text": "file contents"
},
"browser": {
"name": "Firefox"
}
}
```
`file.name` and `file.text` are required for `kind: "file"`. The extension
limits text content to 2 MB so it stays within the current Files API text-read
size and avoids turning local receiver events into large binary transport.
## Receiver Event
The desktop receiver accepts `kind: "file"` and publishes
`browser.capture.file`. The event payload flattens file fields for Browser Inbox:
```js
{
captureId,
capturedAt,
source,
kind: 'file',
url,
title,
domain,
fileName,
fileMime,
fileSize,
fileText,
browserName
}
```
Current workspace annotation continues to work the same as page, selection, and
link captures.
## Browser Inbox Conversion
Browser Inbox subscribes to `browser.capture.file` and stores file fields in its
plugin-owned queue. In a workspace view, file captures render a `Create File`
action.
On success:
- write `<workspaceRootPath>/Files/<safe-file-name>` through
`api.files.writeText`;
- use `{ createIfMissing: true, overwrite: false }`;
- publish `browser.capture.converted` with `conversionType: "file"` and
`filePath`;
- remove the capture from the queue.
On write failure, Browser Inbox leaves the capture in the queue and renders an
error status.
## Testing
Required checks:
- browser extension protocol test builds and validates `kind: "file"`;
- receiver unit test accepts a file capture and publishes
`browser.capture.file`;
- Browser Inbox smoke test verifies `Create File` write path, content, write
options, queue removal, converted event, and failure behavior;
- full repo checks continue to pass for touched repositories.