Skip to content
OpenSmartRoute
Documentation
Apps

Browser extension

The pre-send advisor for ChatGPT, Claude, Gemini, Copilot and Perplexity: risks, redaction, model hints and cost quotes on the device.

Apps 30 min read

The OpenSmartRoute browser extension is a pre-send advisor for the chat sites people already use - ChatGPT, Claude, Gemini, Microsoft Copilot and Perplexity. While you type, a small card next to the composer shows what the request is, how many tokens it carries, whether it contains personal details or pasted secrets, which kind of model it deserves and what it would cost across the OpenSmartRoute catalogue. Everything runs on-device by default; the platform is only involved when you ask for it.

Get it from the product page (store listing or the packaged download for your browser). Chrome and Edge share one package (Manifest V3); Firefox has a build of its own.

What the card shows

The card is quiet by default. It opens by itself only when there is a reason to interrupt you: personal details or a key in the draft, a jailbreak pattern, a held send, a model that will not do what the draft needs, a draft near the model's context limit, or a cheaper model that fits and saves at least a cent on this request. Everything else - small slips, tips, prices for their own sake - waits in the pill by the field (see Anywhere you write) until you click it. Close the card and it stays closed for that draft.

The card leads with one verdict line that is always visible - Nothing flagged, 2 personal details in your draft, An API key is in your draft, GPT-5 Thinking is more than this needs, 3 small slips to fix - with an icon for its tone (shield, alert, tip, check) and a live region so screen readers hear the change. The details underneath open by themselves only when there is something to act on; otherwise they stay folded until you click the chevron, and your choice is remembered for that site (Settings › Checks › Show the card's details by default opens them everywhere). Every detail is one row: an icon, one sentence in plain words, at most one button.

RowSourceWhat you can do
What the router sees (task, tokens, the kind of model it needs - a quick model is enough, a standard model fits, needs a thinking model)On-device signals (a TypeScript port of the router's heuristics)Read it
Personal details (email, phone, card, IBAN, SSN, Aadhaar, IP, API keys and tokens)On-device patterns, the same list the platform's guard usesRedact swaps them in the composer for <EMAIL_1>-style placeholders; Undo puts the original back for 30 seconds. While the send guard holds Enter the row also offers Redact and send and Send anyway
The model the site has selectedThe picker label matched against the catalogue and priced for this draftX fits this request, about $0.002; X is more than this needs - Y does it for about $0.0003 (-90%) when a lighter model of the same vendor fits; X may not be enough when the draft needs reasoning. Switch in the site's picker
Small slips, fillerOn-device writing checksFix repairs typos, doubled words and capitals; Trim removes filler and repeats. Tips that are not mistakes - a missing audience or format, a vague ask - sit behind one line, N tips for a better answer; open it and Add appends the missing line
Your router's pick and priceConnected only: an on-device estimate over the catalogue, or the workspace's quote (POST /api/v1/estimate) when Send my draft to get prices is onThe pick with its price and, when the site's own model is known and dearer by at least half a cent, saves $0.012 vs GPT-5 Thinking - a real comparison, never a percentage against a model you were not going to use. One line for the cheapest and the best, Compare all for the full list, Quoted by followed by the workspace's name in the footer. An anonymous quote that hit the rate limit says when to retry and offers Connect
Improve with your routerConnected onlyProofread, Make clearer, Shorten, Continue - the result is shown first; Use this replaces the draft
Connect your workspaceSigned outOne button to Settings; the public catalogue is never shown as if it were your models

The extension reads only the draft in the composer and the model label. It never reads or changes what the site sends, never blocks a request and never automates the site's UI beyond replacing your own text when you click Redact, Fix, Trim or Use this - and sending it when you click Send anyway or Redact and send on a held draft. On sites that are not one of the five chat sites the card says draft only: the conversation on the page is never read. When a chat site changes its layout and the built-in selectors no longer find the box, the card carries on through the general-purpose selectors and the popup says so.

Anywhere you write, anything you select

The extension behaves like a writing assistant and an AI sidebar at the same time:

  • Writing widget - a small pill sits in the bottom-right corner of the field you are typing in, in any text field once Help in every text field is on and on the chat sites out of the box. It has three controls:
    • the sparkle opens the commands popover: one box (What can OpenSmartRoute help you with?) with the send arrow inside it (grey until there is something to send, Enter sends, Shift+Enter a new line) whose instruction runs on the selection inside the field, or the whole field, through your router. The answer streams: the result panel opens the moment you send, shimmering lines stand in until the first words arrive, the text grows with a caret, and Stop keeps what has come so far. When it is done: Insert / Replace selection, Copy and the target and cost that answered. Starter ideas - Rewrite this text (three variants in a Rephrase / Simplify / More formal / More casual / Shorten / Expand menu, the changed words marked, Show more for another three, one click puts the pick into the field), Fix spelling and grammar, Make it shorter, Summarise, Translate, Draft a reply, Continue writing. Signed out it offers Connect instead;
    • the score - on the chat sites a count: how many things are worth a look before you send (personal details, slips Fix can repair, a model worth changing, a jailbreak pattern); the pill stays empty when there is nothing. Everywhere else a 0-100 writing score computed on the device from the same checks the card runs (spelling, clarity, delivery, style, terms, privacy; personal details and secrets cost the most). Its colour is the risk: green, amber for personal details, red for secrets or financial identifiers - and its label says the same in words. Click it to open or close the card; the card also opens by itself for the reasons listed under What the card shows;
    • the power button (shown on hover) asks Disable OpenSmartRoute suggestions on this site? - Disable until next visit (this browser session), Disable forever (the domain joins Turned off on these sites in Settings, removable there) or Keep it on. The popup's switch for the active tab does the same. Every switch - the power button, the popup, the chat-site switches and the Help in every text field, Where the widget appears and Turned off on these sites controls in Settings - reaches the open tabs at once: the widget goes or comes back without a reload.
  • Selection actions - select at least a dozen characters of text on any enabled page (outside a field you are editing) and, once the mouse settles, a rounded toolbar appears above it: Explain, Summarise, Rewrite, Translate, Fix grammar and Ask. Each runs through the sidebar with the selection attached, so the router picks the model and you see the decision under the answer. The same actions are in the right-click menu, together with Summarise this page and Open routed chat.
  • Your own commands (Settings › Commands) - prompts you save once and run with one click: they join the selection toolbar and the right-click menu next to the built-in actions, the writing widget's commands popover under Your commands, and the desktop app's command bar (the same list, the same shape). Write {{selection}} where the text you selected (or typed in the field) goes; {{page}} (the page's text), {{title}}, {{url}}, {{app}} (the site) and {{language}} are filled in the same way, and a prompt that names no text gets it quoted under it, exactly as Summarise does. {{page}} and {{url}} exist only in the browser: a command that uses them is not offered on the desktop bar, and Settings says so when you tick it. Each command says where it appears (selected text, writing widget, desktop bar - or everywhere); Add three examples seeds Reply in my tone, Turn into a post and Explain for a newcomer to edit. Up to 50 commands, kept in this browser; an organisation can pin the list (commands below).
  • Answer in (Settings › Commands) - the language every routed answer is asked for, in the sidebar and in the commands; empty means the language of the question. It travels as a system line in front of each request.
  • Export (the download icon in the sidebar's header) - the open conversation as a Markdown file through the browser's downloads: who said what, the target and the price under each answer, the attached text quoted. Nothing is uploaded; the file is written from what the sidebar shows.
  • Edge tab and shortcut - on pages that are not one of the chat sites a tab on the right edge slides out to Sidebar and opens the sidebar; click it again (or press Alt+Shift+O again) and the sidebar closes. Right-click the tab to hide it on that site; Alt+Shift+O and the popup work anywhere, including the chat sites, which get no tab of their own. The empty sidebar offers idea tiles - Brainstorm ideas, Plan a project, Create content (each starts a prompt in the box) and Prompt library (the marketplace) - and quick-action tiles - Summarise this page and, for whatever is attached, Explain, Summarise, Rewrite, Translate; a context chip shows what will travel with the next message and can be detached.
  • Help in every text field (Settings › More options, on by default) - the writing widget follows the field you type in on any site: a textarea, a text input, a rich editor (contenteditable, including the ones that live in a frame or in a web component), a classic WYSIWYG frame in design mode. Mail, docs, tickets, forms and CMS editors get the widget without anything to set up; the extension reads only the field you type in, never the page around it. Turn the switch off to keep the advisor to the chat sites and Google Docs; a Revoke row takes the browser's site access back as well. Where the widget appears narrows it to All sites or Only these domains (one per line, *.example.com covers the subdomains); Turned off on these sites lists the domains disabled from the widget (the power button on the widget adds the site you are on, for this visit or for good).
  • Google Docs - a document is a site of its own, on out of the box (Settings › Sites), and works without Help in every text field. Docs paints the page on a canvas, so there is no text field for the widget to sit in and the browser's own selection is always empty; the extension reads the selection from the hidden editor frame Docs types into, places the selection toolbar over the highlighted lines, and finds the pill at the edge of the page. Select a passage and the toolbar's actions (Summarise, Explain, Rewrite, Translate, your own commands) hand it to the sidebar; the card on the pill reads the selection - personal details, slips, the model the request deserves - and Redact, Fix and Use this write the result back over the selection the way a paste does. When Docs will not take the paste the text is put on the clipboard and the card says to press Ctrl+V. With the document's words visible to the extension (Docs offers them to an extension that announces itself before the editor loads; Chrome, Edge and Firefox) the sidebar's Summarise this page reads the document; in Safari it reads the selection alone. Nothing is read from pixels, and nothing is sent until you ask.

Surfaces

SurfaceWhat it is for
Card (on the page)The verdict on your draft and the actions on it. Nothing to configure there
Popup (toolbar icon)Status: the connected workspace (a selector when the profile remembers more than one), one switch for the site in the active tab (a chat site's adapter, or the writing widget on any other site), today's counters (drafts checked, details hidden, tokens saved, model tips) or a one-line hint while there are none, tracked API calls when tracking is on, Open the sidebar, the extension's version, an Update to x.y.z card when a newer build is published and the colour-scheme button (system / light / dark). No settings
Sidebar (edge tab, Alt+Shift+O, popup)Two tabs: Ask - chat through your router, with the decision under every answer - and Suggestions - the writing score of the field you are typing in, its categories and findings with one-click Fix / Add / Redact, and the stats (words, characters, words per sentence, reading time, grade level). Sessions keeps earlier chats of this browser session
Settings (gear in the popup, or the browser's extension options)Everything, in one place, saved as you change it. Four essentials are visible - Workspace (Connect; the platform address, tenant and key live in a Self-hosted or using a key fold), Privacy, Chat sites, Checks - and the rest sits behind More options (help in every text field, where the widget appears, the sites turned off, selection actions, the edge tab, API tracking, one-click connect, model prices). Folds open by themselves when a setting inside them is already on
Welcome (opens once after install)Two steps: 1 Explore features - four slides (the widget, the commands, the score, the sidebar) - and 2 Activate - Connect a workspace (the code sign-in) and Help in every text field (the browser's permission prompt). Both optional, both changeable later; Skip at any point

All surfaces share one design system - the brand palette, a stroke icon set, pills, chips and tiles - and follow the page's colour scheme on the chat sites (a dark ChatGPT under a light OS gets a dark card and the reverse mark). Copy is written for a general reader: no tiers, catalogues or quotes on screen - a quick model is enough, public prices, from your workspace.

Analysis policy

Settings › Privacy › Send my draft to get prices. Connecting a workspace turns it on (personal details hidden first); you can turn it back off.

LevelWhat leaves the browser
Off (default until you connect)Only the public catalogue download (GET /api/v1/models, no user data). Signed out, the card shows the on-device checks and a Connect row - it does not list the public catalogue as if it were your models; connected, an estimate computed on this device from public prices
OnThe draft is sent to POST /api/v1/estimate - anonymously (rate limited) or with your key - after on-device redaction unless you turn that off. The platform stores no request text (activity rows carry request id and metadata only). The card labels the result From your workspace or Anonymous quote · public prices

Keys are kept in chrome.storage.local (not synced) while Stay signed in (Settings › Privacy, on by default) is on; turn it off and the key lives in chrome.storage.session - memory only - and you connect again after the browser restarts. Sign out from the popup or Settings, or revoke the key from the dashboard's API keys page.

Managed by an organisation

An administrator installs the extension in every browser of every account and settles its settings before anyone opens it - no store visit, no developer mode, no first-run choice. Two policies do it, and one command writes both in the shape each browser reads. Download the policy kit from the extension page (/extension/download/policy, the opensmartroute-extension-policy-<version>.zip of the current build), unzip it anywhere with Node.js 18 or newer and run the script it carries:

node policy.mjs --out policy/ --release https://opensmartroute.ai/extension/release.json --settings settings.json

The kit is self-contained - policy.mjs, the managed_schema.json it validates against, a settings.example.json to start from and a README with this command. --release takes the store ids and the signed Firefox package from the website's manifest (explicit --chrome-id, --edge-id, --firefox-xpi win over it); --settings is a JSON object of the keys below. It writes:

FileDeliver with
opensmartroute-extension-windows.regGroup Policy, Intune (as a script or PowerShell reg import), a login script; imports as administrator. HKLM ExtensionInstallForcelist items 900 and 901 for Chrome and Edge (the rest of your list is untouched), 3rdparty\extensions\<id>\policy for the settings, Firefox's ExtensionSettings and 3rdparty\Extensions\<id>
opensmartroute-extension-macos.mobileconfigJamf, Intune, Kandji, Mosyle or any MDM: one profile with a payload per browser (com.google.Chrome, com.microsoft.Edge, their .extensions.<id> settings domains, org.mozilla.firefox)
opensmartroute-extension-firefox-policies.jsonFirefox's distribution/policies.json (Windows, macOS) or /etc/firefox/policies/policies.json (Linux)
opensmartroute-extension-chrome-linux.json, -edge-linux.json/etc/opt/chrome/policies/managed/, /etc/opt/edge/policies/managed/
opensmartroute-extension-ExtensionSettings.jsonGoogle Admin's or Intune's policy editor, when you keep the force-install in your own ExtensionSettings

The settings an administrator may pin (the extension declares them in managed_schema.json; anything else is refused by the script and ignored by the browsers): platformUrl, apiPrefix, tenant, policy, sites, everywhere, siteMode, allowedDomains, blockedDomains, consoles, shareObserved, logActivity, staySignedIn, askBeforeSend, commands (a list of { "id", "label", "prompt", "where" } objects that replaces the person's own commands) and answerLanguage. Pinned keys are shown locked in Settings with Set by your organisation. Chrome and Edge read them from the 3rdparty policy (Software\Policies\Google\Chrome\3rdparty\extensions\<id>\policy or the Edge equivalent; on macOS the com.google.Chrome.extensions.<id> domain), Firefox from policies.json -> 3rdparty.Extensions.<id>:

{ "platformUrl": "https://router.example.com", "apiPrefix": "/api/v1", "tenant": "acme", "policy": "quote", "staySignedIn": false }

Deploying the desktop app for every account? Its Windows installer takes /EXTENSIONS=all and registers the extension for every account itself (an Enable OpenSmartRoute? prompt per person, no policy); the files above are the way to a silent, forced install, and the only way on macOS.

Diagnostics

Settings › More options › Advanced › Copy diagnostics puts a support bundle on the clipboard: version and channel, browser, the platform address, every setting with secrets redacted, which keys are policy-pinned, today's adapter health per site and the last events the worker recorded (quote failures, message errors, install and update). Nothing is uploaded on its own. The popup also tells you when the extension could not find the message box on a chat site today ("the site may have changed", with a Report it link) or when it fell back to its general-purpose mode there.

Connect

Popup or Settings -> Connect. The extension starts a device sign-in (POST /api/v1/auth/device/code), opens the approval page in a tab and polls POST /api/v1/auth/device/token until you approve; the minted key is labelled Browser extension in the dashboard. For a self-hosted osr serve or an existing key, open Settings › Workspace › Self-hosted or using a key, paste the token and set the API style to Self-hosted osr serve.

Once connected, quotes are metered as estimate on your workspace, tenant rules apply (set the tenant in Settings) and the traffic is attributed to the app browser-extension: every call carries X-OSR-App: browser-extension, and the dashboard's Usage page breaks metered calls down by app (GET /api/v1/usage -> by_app), so a workspace can see how much of its routed traffic came from the extension, the CLI or its own integrations.

Several workspaces. A person with more than one workspace (their own and a team's, a customer's) connects each one in turn - the popup's Add and Settings' Add another run the same sign-in - and the browser profile remembers all of them. A Workspace selector appears in the popup once there are two; Settings › Workspace lists them with Use and a forget button. The card's quote row says which one priced the draft (From Acme), the sidebar's header chip names it, and Sign out leaves only that key: another remembered workspace takes over, so a revoked or expired key never leaves you signed out of everything. The list follows Stay signed in the way the key does - on disk while it is on, in memory only while it is off. The workspace record (name, plan) is re-read from the platform when it is over an hour old, so a rename or a plan change reaches the popup.

Routed chat in the sidebar

Click the toolbar icon on Chrome or Edge (click it again to hide the sidebar), or the overview's Open the sidebar on Firefox and Safari (or Continue in the sidebar on the card when you are connected). The sidebar sends your messages to POST /v1/chat/completions with model: "auto" and streams the answer as rendered Markdown (headings, lists, tables, code blocks with their own Copy; never raw HTML). While an answer streams a Stop button takes Send's place; what arrived stays and is marked stopped. Under each answer it shows the decision as chips - answered by the target (on the hosted platform a link that opens the request's trace on the dashboard: the decision, the spans, the outcome), the cost and latency the platform measured, the steps when there were several and backup model when a fallback ran - Copy for the whole answer and thumbs that post POST /api/v1/feedback, so the workspace's learners hear how the answer went. The preference chips in the composer (Balanced, Cheapest, Best, Fastest) set the objective (osr.objective: quality / cost / latency) for every request. Every call the extension makes - quotes, chat, the catalogue refresh, sign-in, the activity uploads - carries a request id and a W3C traceparent, so each one is a traceable row on the workspace with app: browser-extension. Attach selection and Attach the page in the header pull text in from the active tab without leaving the panel; from a chat site, Continue in the sidebar carries the visible turns and your draft across as history. The conversation lives in your workspace, not in the browser: the first question starts a conversation the platform keeps (osr.conversation), every later one sends only the new message and the platform prepends the thread - the last twelve turns verbatim, everything older as a rolling summary - so it survives closing the browser, continues on the desktop app or in another browser, and never re-sends itself. Sessions lists those conversations (marked from the desktop when they started there), reopens or deletes any of them, and still keeps up to twenty browser-only threads from before you connected. A question that reads like a change of subject gets a line under its answer offering Move to a new chat; the platform moves that exchange into a conversation of its own. When you say something about yourself - I work at Northwind, we use Rust, answer briefly, remember that … - a line under the answer confirms what was remembered, and later questions on every client get that context without repeating it; forget … removes it. The settings page's Memory section lists every remembered fact with a bin, an Add field and the switch that turns it off for good. On Chrome and Edge a one-time bubble points at the browser's pin so the panel is one click away. When something fails the status line says what happened in plain words and offers the one action that helps - Try again (the question goes back into the box), Connect (the key was revoked), See plans (the plan's allowance is used up), Open settings (the platform could not be reached).

The Suggestions tab needs no workspace: the content script scores the field on the device and hands the panel the score, the findings and the stats (never the text beyond a 200-character preview). Fix, Add and Redact on a finding change the field in the page; the score follows.

Tracking provider API calls

Two channels, both off until you switch them on in Settings › More options › API tracking.

  • Provider consoles and your own apps - an observe-only webRequest listener on the LLM API hosts (OpenAI, Azure OpenAI, Anthropic, Gemini, OpenRouter, Groq, Mistral, Together, DeepSeek, xAI, Cohere), on localhost / 127.0.0.1 and on any origin you add. It reads the request body (model, messages) and the status, estimates the completion from max_tokens, prices the call from the catalogue and never blocks or changes anything. The browser asks for access to those hosts once. The popup shows today's calls and estimated cost per vendor.
  • DevTools panel (F12 -> OpenSmartRoute) - every LLM call the inspected tab makes with the exact usage from the response body (OpenAI chat and Responses, Anthropic Messages, Gemini, Cohere; JSON and SSE), latency, status, the detected task and the catalogue price; vendor and model chips that narrow the table (the totals follow what is shown - the tab's model mix at a glance); a detail view with the messages and the answer; JSONL / CSV export; and Replay through OpenSmartRoute, which sends the same messages through the router and shows both answers with both costs side by side.

Share what was tracked with my workspace (Settings › More options › API tracking, connected) uploads call shapes - vendor, model, token counts, site, task type, complexity - to POST /api/v1/usage/observed every few minutes. No text field is ever sent; the platform rejects unknown fields (422). The workspace's opportunity report (GET /api/v1/usage/opportunity) compares what those calls cost at list price with what the router's recommended target would have cost for the same token shape.

Activity on the workspace

Log my activity to the workspace (Settings › Advanced, on by default) records what the extension did as events on the connected workspace - POST /api/v1/usage/activity, posted every few minutes with the observed usage. An event is a kind, the site's hostname, a count and a figure; there is no field for text and the platform refuses one. The kinds: card.analysed (a draft checked, with the saving between the card's pick and the dearest candidate), quote.fetched, model.hinted, pii.redacted (with the number of details), draft.compacted (with the tokens saved), writing.fixed, writing.suggested, writing.answered (with the target and request id of the answer written into a text field), send.held, session.signed_in / session.signed_out, extension.installed / extension.updated. The workspace's Apps page turns them into counts per kind and site; the plan decides how long they are kept and how many a day are recorded (see PLATFORM.md). Administrators can pin the switch with the logActivity managed-storage key.

The first event the extension records for a workspace also sends Your browser extension is connected to the person who connected it: what the extension does, that the workspace sees counts only, the Apps page and this guide, and what to do if they did not install it. A workspace that routes through the API for three days without the extension or the desktop app ever reporting in gets one note about the two (Getting started mail, switchable on the account page).

The AI spend page

Signed-in users read the report on /platform/dashboard/spend: observed calls and spend, the router's quote for the same requests, the gap, the models with the widest gap and the target the router would have picked, breakdowns by model, site and task, the per-call history (GET /api/v1/usage/observed, newest first, never any text) and a CSV export. Only calls the catalogue can price count towards the gap, so both sides describe the same requests; the page says so and never calls the number a saving. Rows are kept for 90 days and deleted with the workspace. While nothing has been observed yet the page explains what to install and how to switch sharing on.

Install

The product page /extension on the website is the front door. It detects the visitor's browser (Chrome and the other Chromium browsers, Edge, Firefox, Safari) and offers, in this order:

  1. the store listing for that browser - one click, no developer mode - as soon as the release carries it (stores in latest.json, see below): Chrome Web Store, Microsoft Edge Add-ons, Firefox Add-ons, Mac App Store;
  2. a vendor-signed package that installs from the click: the Firefox build is signed by Mozilla (AMO, unlisted channel) and served as an .xpi, so Add to Firefox installs without about:debugging;
  3. the packaged build for that browser - Download for Chrome / Edge - followed by a guided developer-mode install whose steps follow the selected browser (extensions page address with a copy button, Developer mode, Load unpacked); Safari's package is the Mac app the store will carry;
  4. when no build is published yet, the page says so and shows the same steps for the day it does.

Chrome and Edge cannot install an extension from a website without developer mode - Google and Microsoft removed every non-store path in 2018 - so for those two the store listing is the only one-click install and every stable release is submitted to both stores. The desktop app shortens the wait: Get the extension on its welcome screen downloads the Chrome or Edge package, unpacks it into a folder of its own under the app's data directory and names that folder, so the two clicks left are Developer mode and Load unpacked. The folder is removed again with the extension (Remove in Settings, or uninstalling the app).

The page recognises an installed extension - the platform-origin content script sets data-osr-extension="<version>" on <html> - and turns every call to action into "Installed" with a link to the AI spend page. The Product menu carries the extension as its featured card with a browser-aware "Add to Chrome" button, visitors on a supported browser without the extension see a floating install prompt once per month on the public pages, and signed-in users see a one-time, dismissible suggestion on the dashboard overview and the Usage page.

Where the packages come from. Every release publishes one package per store - Chrome, Edge, Firefox and Safari (the Safari package is a Mac app) - stamped with the release version, or with a four-part preview number for developer previews so no two builds share a file name (see Versions and channels). The Firefox build is signed by Mozilla: previews as a one-click unlisted .xpi, stable releases through the Firefox Add-ons review queue once the listing is live, delivered by the store after approval. Mozilla's review never holds the other browsers back: while signing is pending the manifest lists the Firefox zip in place of the .xpi, and the signed package takes its place once Mozilla has issued it. Stable Chrome and Edge packages are submitted to their stores' review; the product page switches to a store button the moment a listing is approved. Each channel publishes a manifest (latest.json for stable, preview.json for previews) naming every package with its size, SHA-256, kind (zip, xpi, app), signature state and the live store URLs.

The website serves:

  • GET /extension/download/{chrome|edge|firefox|safari} - 302 to the current package for that browser (a Mozilla-signed .xpi for Firefox installs on arrival; Edge takes its own package or Chrome's); the stable release by default, ?channel=preview for the developer preview; 404 while no build is published;
  • GET /extension/download/policy - 302 to the administrator's policy kit of the same build (policy in the manifest), see Managed by an organisation;
  • GET /extension/release.json - the manifest with same-origin download links, for scripts and the extension's own update check (?channel=preview likewise; channel in the answer says which build it is).

Stores and signing without a paid developer programme

No browser needs a paid licence to run the extension; what a paid or verified account buys is the one-click install from the vendor's store. What each browser needs:

BrowserOne-click pathWhat it needsWithout it
FirefoxMozilla signs the package (AMO, unlisted channel) and Add to Firefox installs from the click.A free Firefox account and its API credentials (OSR_EXTENSION_AMO_JWT_ISSUER / _SECRET).Load Temporary Add-on from about:debugging.
EdgeMicrosoft Edge Add-ons listing.A free Partner Center registration for Edge Add-ons; OSR_EXTENSION_EDGE_PRODUCT_ID, _CLIENT_ID and _API_KEY. With them set, every stable version is submitted.Developer mode: download the package, edge://extensions, Load unpacked. Managed devices: the ExtensionSettings force-install policy on the product page installs it without developer mode.
Chrome and other Chromium browsersChrome Web Store listing.A Chrome Web Store developer account (a one-time registration fee, no yearly programme). Register the extension once by hand in the developer dashboard (the store creates no items through the API), note the item id and the publisher id, enable the Chrome Web Store API on a Google Cloud project and give it a service account (added under Developer Dashboard > Account) or a Desktop-app OAuth client. With OSR_EXTENSION_CWS_* set, every stable version is submitted through the Web Store API (V2; the V1 API is switched off on 2026-10-15).Developer mode as for Edge; the ExtensionInstallForcelist policy for managed devices.
SafariMac App Store listing.An Apple Developer Program membership (yearly fee) to sign and notarise the Mac app.The Xcode wrapper is still published; anyone with a free Apple ID opens it in Xcode and runs it on their own Mac (Safari > Settings > Developer > Allow unsigned extensions).

In short: Firefox costs nothing and is signed today, Edge costs nothing but a registration, Chrome a one-time fee, Safari a yearly membership. The product page and the dashboard's Apps page never claim a store that is not configured: they show the signed package, the packaged build with its steps, or the store button - whichever the release manifest can back.

Updates. A store install updates through its store. The signed Firefox .xpi from the downloads page updates itself too: its manifest names /extension/updates.json (the preview build ?channel=preview), Firefox reads it daily, checks the SHA-256 and installs the newer signed package - the same mechanism the store uses. A package installed unpacked on Chrome or Edge and the Safari app have no updater, so the extension asks /extension/release.json for its own channel twice a day (and when you open the overview or the sidebar after that long): a small dot appears on the toolbar icon, the sidebar shows an Update to x.y.z line under its header and the overview an Update to x.y.z card, both linking to the package for your browser and saying what to do (download, then Reload the unpacked folder). Nothing is downloaded or installed by itself on those browsers.

Self-hosted platform. The packages ask permission for https://opensmartroute.ai only. When you enter another platform URL in the options, the browser asks you to allow that site (an optional host permission); decline and the hosted platform stays selected.

While no stable release of the extension has been published yet, the developer preview stands in on both routes and the product page says so ("developer preview" next to the version). Versioned packages are immutable (cached for a year); the two manifests are the moving pointers (cached 5 minutes, mirrored by the website). A stable release publishes the stable packages; every change to the platform publishes a new developer preview. The source repository is private: the downloads and the store listings are the only distribution, and /extension/release.json carries the SHA-256 to verify a package against.

Managed browsers. A web page cannot install an extension by itself (browsers removed inline install in 2018); what installs it automatically for everyone in a company is the ExtensionSettings policy - Group Policy or Intune for Edge and Chrome on Windows, Google Admin for managed Chrome profiles. The product page renders the snippet with the store id (NEXT_PUBLIC_EXTENSION_CHROME_ID / _EDGE_ID):

{ "<extension-id>": { "installation_mode": "force_installed", "update_url": "https://clients2.google.com/service/update2/crx" } }

Edge uses the same shape with https://edge.microsoft.com/extensionwebstorebase/v1/crx.

Loading a downloaded package by hand (the guided installer on /extension shows the same steps for your browser):

  • Chrome: chrome://extensions -> Developer mode -> Load unpacked -> the unzipped folder (the one holding manifest.json).
  • Edge: edge://extensions -> Developer mode -> Load unpacked -> the same folder.
  • Firefox: a signed .xpi installs when you open it; an unsigned zip loads through about:debugging#/runtime/this-firefox -> Load Temporary Add-on -> manifest.json.
  • Safari: unzip the app, move OpenSmartRoute.app to Applications, open it once, then Safari > Settings > Extensions; an unsigned build needs Develop > Allow unsigned extensions first.

The same packages can be built from a checkout with npm run build:all (or one of build:chrome, build:edge, build:firefox, build:safari), npm run safari:xcode (macOS: the Xcode project and app) and npm run pack (zips + the channel manifest in dist/).

Permissions: storage, alarms, sidePanel, webRequest (observe-only; no install warning), contextMenus, scripting and activeTab (page summaries and waking the tabs already open when a setting changes), and every http / https site for the content script - the writing widget works in any text field out of the box, so the browser names that at install (Firefox asks for it the first time instead; until it is granted the advisor runs on the chat sites and Google Docs alone). The hosted platform origin (https://opensmartroute.ai) is where the worker talks to. A published package carries no local address (localhost, 127.0.0.1), so the one-click connect bar never runs on a site you are developing. A self-hosted platform URL on another origin - a local osr serve included - is requested when you save it.

Test

Every package is installed into a real Chrome, Edge and Firefox and driven through a sign-in, a redaction and a routed request before it is published. Nothing reaches a store or the downloads page until those checks pass.

Design

The card and the pages follow the brand guide: the real mark (positive artwork on light surfaces, reverse on dark), the Quicksand wordmark with Smart in the cyan text tone, the website's editorial palette in both colour schemes - warm cream and charcoal neutrals (paper, snow, mist, line, ink, slate, muted) and one warm accent, clay, for everything you can press or follow (primary buttons, the send control, switches, links, focus rings, the streaming caret, the toolbar badge) - hairline rules instead of shadows for emphasis, mono numerals in the quote ledger and the three brand hues reserved for the mark, the tier badge, the pick labels and informational chips. Icons are the website's set (lucide, one stroke weight) and every one names the thing it stands for - a pen for rewrite, a spell-check mark for fix, a power button for turn off here; the generic sparkles and wands are not used anywhere. The extension, the desktop app and the site share one look. The extension's own pages (popup, sidebar, Settings, welcome, DevTools) follow the system colour scheme or the one pinned under Settings › Appearance (also the sun / moon / monitor button in the popup and sidebar header); the card and the widget follow the page they sit on, so a dark ChatGPT under a light OS gets a dark card. The card sits just above the composer, right-aligned with it, collapses to a single line, folds long candidate lists behind Show all, shows a loading row while a draft is first analysed and respects prefers-reduced-motion.

Privacy summary

  • Default policy is local only; nothing about your prompt leaves the browser.
  • With the quote policy, personal details are redacted on-device before the draft is sent.
  • The verdict says Nothing flagged - no personal-detail patterns were found (emails, phones, cards, IBAN, SSN, Aadhaar, IP addresses, API keys). Names, addresses and free-text facts are not detected; read before you send.
  • No third-party analytics. What reaches your workspace is the activity described under Activity on the workspace - counts, token estimates, the site category, the target that answered, never text - and, only if you switch it on, the model and token counts observed on the chat sites. No remote code: the heuristics and adapters are bundled; the catalogue is data. Diagnostics are copied by you, never uploaded.
  • Keys are stored locally (or in memory only with Stay signed in off), never synced, and can be revoked from the dashboard at any time.

Something wrong or out of date on this page? Tell us - the page is named for you, so a one-line note is enough.