docs: plan browser inbox text file attachments
This commit is contained in:
parent
bd7558d2f9
commit
5be14d5ec0
|
|
@ -160,6 +160,8 @@ case.selected
|
|||
browser.capture.page
|
||||
browser.capture.selection
|
||||
browser.capture.link
|
||||
browser.capture.file
|
||||
browser.capture.converted
|
||||
```
|
||||
|
||||
Текущий статус: базовый `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
|
||||
`browser.capture.converted` event, which Activity records through its public
|
||||
provider subscription. Browser Inbox also creates human-readable `.url` link
|
||||
files through the public Files API. File attachment capture/conversion is still
|
||||
future work.
|
||||
files through the public Files API. It now accepts selected text files from the
|
||||
browser extension and creates ordinary workspace files through the public Files
|
||||
API. Binary attachment capture/conversion remains future work.
|
||||
|
||||
## 9. `official.search`
|
||||
|
||||
|
|
|
|||
|
|
@ -57,8 +57,9 @@ Known remaining gaps:
|
|||
- Browser extension repository has protocol, queue, and Chromium/Firefox build
|
||||
scaffold; desktop has a local receiver and mounted-view inbox plugin; receiver
|
||||
pairing, basic Browser Inbox domain binding, create-note conversion, and
|
||||
create-link conversion are implemented, and Activity records conversions.
|
||||
File attachment capture/conversion remains future work.
|
||||
create-link conversion are implemented, text file attachment conversion is
|
||||
implemented, and Activity records conversions. Binary attachment
|
||||
capture/conversion remains future work.
|
||||
- Packaging/update/release workflow is not product-grade yet.
|
||||
|
||||
## 4. Implementation Phases
|
||||
|
|
@ -169,7 +170,8 @@ Tasks:
|
|||
- [x] convert inbox entries into notes through public plugin APIs;
|
||||
- [x] record converted inbox entries in Activity through public plugin events;
|
||||
- [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.
|
||||
|
||||
Verification:
|
||||
|
|
@ -240,7 +242,7 @@ Verification:
|
|||
4. [x] Notes trash/delete UX in `verstak-official-plugins`.
|
||||
5. [x] Sync hardening pass with expanded real two-vault smoke.
|
||||
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
|
||||
that depend on them.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
Loading…
Reference in New Issue