diff --git a/05_Official_Plugins.md b/05_Official_Plugins.md index 27852bd..6ee8373 100644 --- a/05_Official_Plugins.md +++ b/05_Official_Plugins.md @@ -254,7 +254,9 @@ Inbox stores plugin-owned `domainBindings` and routes unscoped captures with an 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. Link/file-specific conversions are still future work. +provider subscription. Browser Inbox also creates human-readable `.url` link +files through the public Files API. File attachment capture/conversion is still +future work. ## 9. `official.search` diff --git a/07_Full_Implementation_Roadmap.md b/07_Full_Implementation_Roadmap.md index eb46e0c..f1befcc 100644 --- a/07_Full_Implementation_Roadmap.md +++ b/07_Full_Implementation_Roadmap.md @@ -57,8 +57,8 @@ 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 - Activity recording for conversions are implemented, but link/file-specific - conversion workflows remain. + create-link conversion are implemented, and Activity records conversions. + File attachment capture/conversion remains future work. - Packaging/update/release workflow is not product-grade yet. ## 4. Implementation Phases @@ -168,7 +168,8 @@ Tasks: - [x] add domain-to-workspace binding; - [x] convert inbox entries into notes through public plugin APIs; - [x] record converted inbox entries in Activity through public plugin events; -- convert inbox entries into links/files through public +- [x] convert inbox entries into link files through public plugin APIs; +- convert captured file attachments through public plugin APIs. Verification: @@ -239,7 +240,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; link/file conversions remain. + minimal inbox plugin are implemented; file 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-create-link-conversion.md b/docs/superpowers/plans/2026-06-29-browser-inbox-create-link-conversion.md new file mode 100644 index 0000000..8f5f142 --- /dev/null +++ b/docs/superpowers/plans/2026-06-29-browser-inbox-create-link-conversion.md @@ -0,0 +1,100 @@ +# Browser Inbox Create Link 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 Browser Inbox conversion workflow that creates an ordinary `.url` link file from a captured URL. + +**Architecture:** Keep conversion behavior in `verstak.browser-inbox`. The plugin writes a human-readable `.url` file through `api.files.writeText`, publishes `browser.capture.converted`, and leaves Activity/other consumers decoupled through the event bus. + +**Tech Stack:** Plain JavaScript official plugin bundle, Node smoke test harness, Markdown docs. + +## Global Constraints + +- Do not add a core link entity model in this slice. +- Do not call private APIs from Browser Inbox. +- Use only public plugin APIs: `api.files.writeText` and `api.events.publish`. +- Do not silently rename on link path conflict; rely on `overwrite: false`. +- Use TDD: write the failing smoke test first, run it red, then implement. + +--- + +### Task 1: Browser Inbox Create Link 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` + +**Interfaces:** +- Consumes: + - `api.files.writeText(relativePath, content, { createIfMissing: true, overwrite: false })` + - `api.events.publish('browser.capture.converted', payload)` +- Produces: + - `Create Link` action for workspace-scoped URL captures. + - `browser.capture.converted` event with `conversionType: "link"`. + +- [ ] **Step 1: Write the failing smoke test** + +Add a scenario to `scripts/smoke-browser-inbox-plugin.js` that clicks +`data-browser-inbox-action="create-link"` and asserts the written path, +`.url` 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 Link` is not rendered. + +- [ ] **Step 3: Implement conversion** + +Add helpers in `plugins/browser-inbox/frontend/src/index.js`: + +- `safeLinkFilename(title)`; +- `captureToUrlShortcut(capture)`; +- `createLinkFromCapture(capture)`. + +Render a `Create Link` button for captures with `workspaceRootPath` and `url`. +On success, remove the capture and publish `browser.capture.converted`. + +- [ ] **Step 4: 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-link conversion behavior. +- Produces docs that mark link file conversion done while leaving file attachment capture for later. + +- [ ] **Step 1: Update docs** + +Describe Browser Inbox create-link conversion through the public Files API and +mark link conversion as complete. + +- [ ] **Step 2: Verify docs** + +Run: + +```bash +cd /home/mirivlad/git/verstak2/verstak-docs +git diff --check +rg -n "Create Link|link conversion|file attachment|browser.capture.converted" 05_Official_Plugins.md 07_Full_Implementation_Roadmap.md +``` + +Expected: `git diff --check` exits 0 and `rg` shows updated status lines. diff --git a/docs/superpowers/specs/2026-06-29-browser-inbox-create-link-conversion-design.md b/docs/superpowers/specs/2026-06-29-browser-inbox-create-link-conversion-design.md new file mode 100644 index 0000000..c190528 --- /dev/null +++ b/docs/superpowers/specs/2026-06-29-browser-inbox-create-link-conversion-design.md @@ -0,0 +1,74 @@ +# Browser Inbox Create Link Conversion Design + +## Purpose + +Browser captures should be convertible into a lightweight link artifact without +forcing every URL into Notes. This slice adds a public Files API conversion that +creates an ordinary human-readable `.url` file in the workspace. + +## Scope + +This slice adds one conversion action inside `verstak.browser-inbox`: + +- render `Create Link` for captures that have both `workspaceRootPath` and a + URL; +- write a `.url` shortcut file to `/Links/.url` + through `api.files.writeText`; +- publish `browser.capture.converted` with `conversionType: "link"`; +- remove the converted capture from the inbox queue after a successful write; +- leave the capture in place and show an error if the write fails. + +It does not add a core link entity model, a link resolver plugin, bulk +conversion, or file attachment capture. + +## Link File Format + +The generated file is a plain text Internet shortcut: + +```ini +[InternetShortcut] +URL=https://example.com/article +``` + +The plugin writes with: + +```js +api.files.writeText(linkPath, content, { + createIfMissing: true, + overwrite: false +}) +``` + +This preserves explicit conflict behavior. The plugin must not silently append a +suffix when a link file already exists. + +## Event Contract + +After a successful conversion the plugin publishes: + +```js +api.events.publish('browser.capture.converted', { + captureId, + conversionType: 'link', + linkPath, + workspaceRootPath, + title, + url, + sourcePluginId: 'verstak.browser-inbox' +}) +``` + +Activity can record this through the already-supported +`browser.capture.converted` event. + +## Testing + +`scripts/smoke-browser-inbox-plugin.js` must prove: + +- a workspace capture with a URL renders `Create Link`; +- clicking it writes the `.url` file 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: "link"`; +- when the write rejects, the capture remains in the queue and an error status + is rendered.