From 5be14d5ec06855d18c3ec260f00314d302351082 Mon Sep 17 00:00:00 2001 From: mirivlad Date: Mon, 29 Jun 2026 09:57:21 +0800 Subject: [PATCH] docs: plan browser inbox text file attachments --- 05_Official_Plugins.md | 7 +- 07_Full_Implementation_Roadmap.md | 10 +- ...6-29-browser-inbox-text-file-attachment.md | 171 ++++++++++++++++++ ...owser-inbox-text-file-attachment-design.md | 112 ++++++++++++ 4 files changed, 294 insertions(+), 6 deletions(-) create mode 100644 docs/superpowers/plans/2026-06-29-browser-inbox-text-file-attachment.md create mode 100644 docs/superpowers/specs/2026-06-29-browser-inbox-text-file-attachment-design.md diff --git a/05_Official_Plugins.md b/05_Official_Plugins.md index 6ee8373..a6053ea 100644 --- a/05_Official_Plugins.md +++ b/05_Official_Plugins.md @@ -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` diff --git a/07_Full_Implementation_Roadmap.md b/07_Full_Implementation_Roadmap.md index f1befcc..c598cee 100644 --- a/07_Full_Implementation_Roadmap.md +++ b/07_Full_Implementation_Roadmap.md @@ -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. diff --git a/docs/superpowers/plans/2026-06-29-browser-inbox-text-file-attachment.md b/docs/superpowers/plans/2026-06-29-browser-inbox-text-file-attachment.md new file mode 100644 index 0000000..6967fe0 --- /dev/null +++ b/docs/superpowers/plans/2026-06-29-browser-inbox-text-file-attachment.md @@ -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. diff --git a/docs/superpowers/specs/2026-06-29-browser-inbox-text-file-attachment-design.md b/docs/superpowers/specs/2026-06-29-browser-inbox-text-file-attachment-design.md new file mode 100644 index 0000000..427e269 --- /dev/null +++ b/docs/superpowers/specs/2026-06-29-browser-inbox-text-file-attachment-design.md @@ -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 `/Files/` 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.