diff --git a/bundled-addons/docx-editor/addon.json b/bundled-addons/docx-editor/addon.json index 435cbe4..9dab536 100644 --- a/bundled-addons/docx-editor/addon.json +++ b/bundled-addons/docx-editor/addon.json @@ -4,7 +4,7 @@ "version": "0.1.1", "description": "Open, edit and save Word documents (.docx) in a full Theseus tab, or export them as PDF. Ribbon-style formatting, tables, lists, images and links; headers, footers, footnotes, page setup and the document's own styles are carried through a save untouched.", "author": "Silent Mode", - "icon": "data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20role%3D%22img%22%20aria-label%3D%22Word%20editor%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22dx-page%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23ffffff%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23e9edf4%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cpath%20d%3D%22M6.5%202.5h12l7%207v20a1%201%200%200%201-1%201h-18a1%201%200%200%201-1-1v-26a1%201%200%200%201%201-1z%22%20fill%3D%22url(%23dx-page)%22%20stroke%3D%22%232a3242%22%20stroke-width%3D%221.5%22%20stroke-linejoin%3D%22round%22%2F%3E%3Cpath%20d%3D%22M18.5%202.5v7h7%22%20fill%3D%22%23cfd8e6%22%20stroke%3D%22%232a3242%22%20stroke-width%3D%221.5%22%20stroke-linejoin%3D%22round%22%2F%3E%3Crect%20x%3D%229.5%22%20y%3D%2213%22%20width%3D%229%22%20height%3D%222.2%22%20rx%3D%221.1%22%20fill%3D%22%230ac18e%22%2F%3E%3Crect%20x%3D%229.5%22%20y%3D%2217.6%22%20width%3D%2213%22%20height%3D%221.6%22%20rx%3D%22.8%22%20fill%3D%22%2397a3b6%22%2F%3E%3Crect%20x%3D%229.5%22%20y%3D%2221%22%20width%3D%2213%22%20height%3D%221.6%22%20rx%3D%22.8%22%20fill%3D%22%2397a3b6%22%2F%3E%3Crect%20x%3D%229.5%22%20y%3D%2224.4%22%20width%3D%228.5%22%20height%3D%221.6%22%20rx%3D%22.8%22%20fill%3D%22%2397a3b6%22%2F%3E%3Cg%20transform%3D%22translate(20.4%2019.2)%22%3E%3Ccircle%20cx%3D%224.6%22%20cy%3D%224.6%22%20r%3D%225.4%22%20fill%3D%22%230ac18e%22%2F%3E%3Cpath%20d%3D%22M6.6%201.9H3.9a1.85%201.85%200%200%200%200%203.7h.8M5.3%201.9v5.6M6.6%201.9v5.6%22%20fill%3D%22none%22%20stroke%3D%22%230a0f16%22%20stroke-width%3D%221.15%22%20stroke-linecap%3D%22round%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E", + "icon": "data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M6%202h8l6%206v12a2%202%200%200%201-2%202H6a2%202%200%200%201-2-2V4a2%202%200%200%201%202-2z%22%20fill%3D%22%232563eb%22%2F%3E%3Cpath%20d%3D%22M14%202v6h6z%22%20fill%3D%22%231e40af%22%2F%3E%3Cg%20fill%3D%22%23fff%22%3E%3Cpath%20d%3D%22M12.3%208.6a3.1%203.1%200%200%200%200%206.2z%22%2F%3E%3Crect%20x%3D%2212.05%22%20y%3D%228.6%22%20width%3D%221.7%22%20height%3D%2210.8%22%20rx%3D%22.2%22%2F%3E%3Crect%20x%3D%2214.85%22%20y%3D%228.6%22%20width%3D%221.7%22%20height%3D%2210.8%22%20rx%3D%22.2%22%2F%3E%3Crect%20x%3D%2212.05%22%20y%3D%228.6%22%20width%3D%224.5%22%20height%3D%221.7%22%20rx%3D%22.2%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E", "main": "index.js", "capabilities": [ "sidebar-panel", diff --git a/bundled-addons/docx-editor/icon-128.png b/bundled-addons/docx-editor/icon-128.png index 8444ed5..64bcaa1 100644 Binary files a/bundled-addons/docx-editor/icon-128.png and b/bundled-addons/docx-editor/icon-128.png differ diff --git a/bundled-addons/docx-editor/icon-16.png b/bundled-addons/docx-editor/icon-16.png index 557e864..c69dc44 100644 Binary files a/bundled-addons/docx-editor/icon-16.png and b/bundled-addons/docx-editor/icon-16.png differ diff --git a/bundled-addons/docx-editor/icon-256.png b/bundled-addons/docx-editor/icon-256.png index 1e0dd46..dca970b 100644 Binary files a/bundled-addons/docx-editor/icon-256.png and b/bundled-addons/docx-editor/icon-256.png differ diff --git a/bundled-addons/docx-editor/icon-32.png b/bundled-addons/docx-editor/icon-32.png index 7400ae4..4d4bc80 100644 Binary files a/bundled-addons/docx-editor/icon-32.png and b/bundled-addons/docx-editor/icon-32.png differ diff --git a/bundled-addons/docx-editor/icon-48.png b/bundled-addons/docx-editor/icon-48.png index ead429d..c19dcd3 100644 Binary files a/bundled-addons/docx-editor/icon-48.png and b/bundled-addons/docx-editor/icon-48.png differ diff --git a/bundled-addons/docx-editor/icon.svg b/bundled-addons/docx-editor/icon.svg index 410e318..a82386d 100644 --- a/bundled-addons/docx-editor/icon.svg +++ b/bundled-addons/docx-editor/icon.svg @@ -1,42 +1,27 @@ - - Word editor + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + diff --git a/docs/DESIGN-one-extension-catalogue.md b/docs/DESIGN-one-extension-catalogue.md new file mode 100644 index 0000000..aac49fb --- /dev/null +++ b/docs/DESIGN-one-extension-catalogue.md @@ -0,0 +1,87 @@ +# One catalogue, one set of rules + +Status: proposed, 2026-09-22. Not implemented. + +Theseus currently runs two extension systems that happen to produce the same +kind of thing. + +| | Bundled add-ons | Community extensions | +|----------------|-------------------------------------|---------------------------------------| +| How it arrives | compiled into the build, seeded into the profile on first run | installed from the gateway catalogue | +| Who signs | the Silent Mode operator's Ed25519 key, pubkeys compiled into the app | the owner of a BNS name, checked against the chain | +| Update channel | `theseus.x/extensions//updates.json` | `theseus.x/extensions/community//updates.json` | +| In Settings | a section headed "Built into Theseus" | a separate section headed "Community" | +| How to publish | `scripts/sign-addon-update.mjs` + `sia-upload` | the publish page, or `PUT /api/ext/…` | + +Two catalogues in the UI, two trust rules, two publishing paths — for a +difference that is really only "who wrote it" and "is it there on day one". + +## What this should be instead + +**One catalogue.** Every extension is listed in the same place, whoever wrote +it. Silent Mode publishes under a Silent Mode name the same way anyone else +publishes under theirs. Being first-party is a fact about the publisher, not +a separate distribution system, and the UI should say so with a line of text +rather than a second list. + +**One rule for trust.** An extension is installable because a signature +checks out against the current owner of the publisher's name. That is +already what `verifyPublisherEntry` does; the operator Ed25519 key becomes +either one more accepted signer or nothing at all. `pickChannelEntry` +already accepts both, so this is mostly deletion. + +**Defaults are configuration.** Which extensions a fresh Theseus starts with +is a list of ids in the app's config, not a folder that gets copied. Changing +the default set should be editing that list, not moving directories around +and rebuilding. + +## The one thing that needs care + +If defaults are fetched from the catalogue on first run, a fresh install with +no network — or with the gateway down — has no editor, no wallet and no +screenshot tool. That is a real regression from today, where the build +carries them. + +So keep shipping the code, but stop treating it as a different kind of thing: + +- The build continues to include the default extensions' folders. They are a + **pre-seeded cache**, not a separate class of add-on. +- On first run they are installed from that cache, then verified and updated + against the catalogue exactly like anything the user installed by hand. +- If a seeded copy fails verification, it is quarantined rather than run — + a cache is only a cache. + +That keeps offline first-run working while leaving one set of rules +everywhere else. + +## Sketch of the work + +- **Config**: `defaultExtensions: [{ id, publisher }]` in the app's settings, + read at first run and on profile migration. Ids the user has removed are + remembered and not re-seeded — uninstalling a default must stick. +- **`main.js`**: seeding installs *through* the normal install path instead + of copying a folder and calling it built-in. One code path, one place where + a signature is checked. +- **`settings.html`**: one list. "Installed by default" becomes a badge on a + row, next to the publisher's name. The separate Community section and its + Install button fold into the single catalogue view. +- **`addon-updater.js`**: drop the distinction between the two channel + shapes; an extension has a publisher and an updates URL. +- **Gateway**: the catalogue gains first-party entries. Nothing changes + structurally — `/api/ext` already stores whatever a name owner signs. +- **Publishing**: `scripts/sign-addon-update.mjs` and the operator key stop + being the first-party route. Silent Mode's own extensions go through + `PUT /api/ext///` like everyone else's, which means + the release process needs that name's wallet rather than a key file. + +## Open questions + +- **Which name publishes Silent Mode's extensions?** Whoever goes first owns + each id permanently. Worth deciding once, deliberately. +- **Pinning.** A default extension is installed without anyone choosing it, + so a compromised or coerced catalogue entry reaches every fresh profile. + Pinning the default set to a version and a publisher in the app's config + bounds that. +- **Does the operator key survive at all?** Keeping it as an accepted signer + for the default set is a hedge against the name-owner key being lost; + keeping it forever means the two-rules problem never fully goes away.