docs: plan browser inbox note conversion

This commit is contained in:
mirivlad 2026-06-29 09:36:53 +08:00
parent 2564f6ca9d
commit 40537e9df6
4 changed files with 216 additions and 6 deletions

View File

@ -251,8 +251,10 @@ the global sidebar view aggregates queues from all workspaces plus unscoped
global captures. The local receiver now has an opt-in paired mode that requires global captures. The local receiver now has an opt-in paired mode that requires
`X-Verstak-Receiver-Token` before publishing browser capture events. Browser `X-Verstak-Receiver-Token` before publishing browser capture events. Browser
Inbox stores plugin-owned `domainBindings` and routes unscoped captures with an Inbox stores plugin-owned `domainBindings` and routes unscoped captures with an
exact domain match into the bound workspace queue. Conversion into exact domain match into the bound workspace queue. Its first conversion workflow
notes/links/files/activity is still future work. creates ordinary Markdown notes through the public Files API and publishes a
`browser.capture.converted` event. Link/file/activity-specific conversions are
still future work.
## 9. `official.search` ## 9. `official.search`

View File

@ -56,8 +56,8 @@ Known remaining gaps:
rendering through the public Files API. rendering through the public Files API.
- 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 and basic Browser Inbox domain binding are implemented, but no pairing, basic Browser Inbox domain binding, and create-note conversion are
conversion workflow yet. implemented, but link/file/activity-specific conversion workflows remain.
- Packaging/update/release workflow is not product-grade yet. - Packaging/update/release workflow is not product-grade yet.
## 4. Implementation Phases ## 4. Implementation Phases
@ -165,7 +165,8 @@ Tasks:
page title, and link captures; page title, and link captures;
- [x] define local receiver permission/pairing model; - [x] define local receiver permission/pairing model;
- [x] add domain-to-workspace binding; - [x] add domain-to-workspace binding;
- convert inbox entries into notes/links/files/activity events through public - [x] convert inbox entries into notes through public plugin APIs;
- convert inbox entries into links/files/activity events through public
plugin APIs. plugin APIs.
Verification: Verification:
@ -236,7 +237,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; conversion workflows remain. minimal inbox plugin are implemented; link/file/activity conversions remain.
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,108 @@
# Browser Inbox Create Note Conversion 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 a first Browser Inbox conversion workflow that creates an ordinary Markdown note from a capture.
**Architecture:** Keep conversion behavior in `verstak.browser-inbox`. The plugin uses only public `api.files.writeText` and `api.events.publish`, removes the capture after a successful conversion, and leaves conversion consumers decoupled through the event bus.
**Tech Stack:** Plain JavaScript official plugin bundle, Node smoke test harness, plugin manifest permissions, Markdown docs.
## Global Constraints
- Do not move Browser Inbox conversion workflows into desktop core.
- Do not call Notes, Activity, Journal, or Search private APIs.
- Use only public plugin APIs: `api.files.writeText` and `api.events.publish`.
- Do not silently rename on note path conflict; rely on `overwrite: false`.
- Use TDD: write the failing smoke test first, run it red, then implement.
---
### Task 1: Browser Inbox Create Note Conversion
**Files:**
- Modify: `/home/mirivlad/git/verstak2/verstak-official-plugins/scripts/smoke-browser-inbox-plugin.js`
- Modify: `/home/mirivlad/git/verstak2/verstak-official-plugins/plugins/browser-inbox/frontend/src/index.js`
- Modify: `/home/mirivlad/git/verstak2/verstak-official-plugins/plugins/browser-inbox/plugin.json`
**Interfaces:**
- Consumes:
- `api.files.writeText(relativePath, content, { createIfMissing: true, overwrite: false })`
- `api.events.publish('browser.capture.converted', payload)`
- Produces:
- `Create Note` action for workspace-scoped captures.
- `browser.capture.converted` event after successful conversion.
- [ ] **Step 1: Write the failing smoke test**
Add fake API support for `files.writeText` and `events.publish` in
`scripts/smoke-browser-inbox-plugin.js`, then add a scenario that clicks
`data-browser-inbox-action="create-note"` and asserts the written path,
Markdown content, write options, queue removal, and published event.
- [ ] **Step 2: Run RED**
Run:
```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: fails because `Create Note` is not rendered.
- [ ] **Step 3: Implement conversion**
Add helpers in `plugins/browser-inbox/frontend/src/index.js`:
- `noteTitle(capture)`;
- `safeNoteFilename(title)`;
- `captureToMarkdown(capture)`;
- `createNoteFromCapture(capture)`.
Render a `Create Note` button for captures with a workspace root. On success,
remove the capture and publish `browser.capture.converted`.
- [ ] **Step 4: Update manifest permissions**
Add `files.write` and `events.publish` to
`plugins/browser-inbox/plugin.json`.
- [ ] **Step 5: Run GREEN**
Run:
```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
PATH=/tmp/verstak2-tools/venv/bin:/tmp/verstak2-tools:/home/mirivlad/.lmstudio/.internal/utils:$PATH ./scripts/check.sh
```
Expected: both commands exit 0.
### Task 2: 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 create-note conversion behavior.
- Produces docs that mark note conversion done while leaving link/file/activity conversion for later.
- [ ] **Step 1: Update docs**
Describe Browser Inbox create-note conversion through the public Files API and
mark only note conversion as complete.
- [ ] **Step 2: Verify docs**
Run:
```bash
cd /home/mirivlad/git/verstak2/verstak-docs
git diff --check
rg -n "Create Note|note conversion|conversion workflow|notes/links/files/activity" 05_Official_Plugins.md 07_Full_Implementation_Roadmap.md
```
Expected: `git diff --check` exits 0 and `rg` shows updated status lines.

View File

@ -0,0 +1,99 @@
# Browser Inbox Create Note Conversion Design
## Purpose
Browser Inbox should turn a captured page, selection, or link into useful vault
material without knowing Notes internals. This first conversion slice creates an
ordinary Markdown note through the public Files API.
## Scope
This slice adds one conversion action inside `verstak.browser-inbox`:
- render `Create Note` for captures that have a `workspaceRootPath`;
- write a Markdown file to `<workspaceRootPath>/Notes/<safe-title>.md` using
`api.files.writeText`;
- publish `browser.capture.converted` after a successful write;
- remove the converted capture from the inbox queue;
- leave the capture in place and show an error if the write fails.
It does not add a separate Notes plugin API, link entity model, file attachment
conversion, bulk conversion, or Activity/Journal-specific UI. Other plugins can
react to the published conversion event through the public event bus.
## Note Path And Content
The generated note filename is a human-readable safe projection of the capture
title:
1. Prefer capture `title`.
2. Fall back to capture `domain`.
3. Fall back to capture `captureId`.
4. Replace unsafe filename characters with `_`.
5. Append `.md`.
The plugin writes with:
```js
api.files.writeText(notePath, markdown, {
createIfMissing: true,
overwrite: false
})
```
This preserves explicit conflict behavior. The plugin must not silently append a
suffix when a note already exists.
Markdown content:
```md
# <title>
Source: <url>
Captured: <capturedAt>
Kind: <kind>
<captured text when present>
```
Missing URL or text sections are omitted.
## Event Contract
After a successful conversion the plugin publishes:
```js
api.events.publish('browser.capture.converted', {
captureId,
conversionType: 'note',
notePath,
workspaceRootPath,
title,
url,
sourcePluginId: 'verstak.browser-inbox'
})
```
The event is informational. Browser Inbox does not require Activity to be
installed and does not directly call Activity, Notes, Journal, or Search.
## Permissions
`verstak.browser-inbox` must add:
- `files.write`;
- `events.publish`.
Existing permissions remain unchanged.
## Testing
`scripts/smoke-browser-inbox-plugin.js` must prove:
- a workspace capture renders `Create Note`;
- clicking it writes the Markdown note through `api.files.writeText`;
- the write uses `createIfMissing: true` and `overwrite: false`;
- the capture is removed from its queue after success;
- `browser.capture.converted` is published with `conversionType: "note"`;
- when the write rejects, the capture remains in the queue and an error status
is rendered.