Spindle for Browser · built on Spindle and the Dext engine
An agent that lives in your browser.
From open tabs to finished work, with a workspace you can rewind and take with you. Research across pages. Run Python and JavaScript. Build reports, datasets and small applications in a Linux environment inside your browser.
Open source. Bring your own model. No required desktop app or backend.
Tested on Chrome, Edge and Brave (Chromium 116 or later), on desktop. Not in the Chrome Web Store yet.
The second shop is cheapest on four of five items.
prices.csv and chart.svg are in the workspace.
A whole agent, carried into the browser.
Not a chat box that talks to someone's server: the Spindle engine itself, compiled to WebAssembly and running in your browser, with a Linux beside it.
Keeps going with the panel closed.
Threads run in an offscreen worker, not in the panel. Close it, switch tabs, and come back to the answer.
A real shell, inside the browser.
bash, coreutils, Python 3 with pip, Node with npm, git, curl, jq and ripgrep in Alpine Linux. Each command runs in namespaces of its own, over a copy of the thread's workspace.
Reads and works your pages.
With page reading on: list, read and outline tabs. With page actions on: click, type, select, scroll, navigate, answer dialogs and record a tab's network.
Scripts that call the agent.
From a command, spindle model, spindle tool and spindle http;
from Python import spindle; from Node require('spindle'). Every call is
journaled like any other step.
Files in, files out.
Drop files on the panel or picture a tab. Get files back as cards, HTML as a sandboxed preview
that reaches no site until you allow it (where the browser cannot hold it offline, its scripts wait
for you too), Word, Excel and PowerPoint files drawn in place with nothing in them running, PDFs
in the browser's own viewer, audio and video to play, and everything as one .zip.
Sealed, never sent elsewhere.
Keys and sign-ins are sealed with AES-GCM in the extension's storage, under an optional passphrase, and go only to the provider they were saved for. Or sign in with ChatGPT.
Interrupt it. It keeps its word.
A browser is a hard place for long work: tabs close, workers rest, the browser quits. Every thread here is a Spindle session, so each step is committed before the next begins.
The browser closes mid-turn.
When it starts again, the thread is there, marked interrupted, with every committed step kept. Continue takes it on from there.
Nothing is sent twice by itself.
A model request whose fate is unknown is shown as unknown. Continue never resends it; Retry sends it once more, on your word.
Go back to before a message.
The conversation and the workspace's files return together, so no file from the undone future is left in the workspace.
Take a thread with you.
Move it to your connected Spindle host from its menu, or to a
.spindlefile, and go on with native Spindle on your machine, in its sandbox with its full tools. Then bring it back.
Work that starts on a web page.
Pull data out of pages.
Read several tabs, gather what they say into a CSV, and chart it with Python, without copying a cell by hand.
Do the clicking for you.
Fill in a long form or walk a settings page, one action at a time, on the page you are looking at.
Build a small app and see it.
Write HTML and JavaScript, open it in a preview, change it, and download the folder when it works.
Make sense of a file.
Drop in a log, a spreadsheet export or a JSON dump and ask what is in it. Python does the counting; you get the answer and the script.
See what a page loads.
Record a tab's requests and read the responses, to find the call behind a broken button.
Research across tabs.
Compare what several pages say and keep a written summary in the workspace, with where each claim came from.
In your browser, or wherever you work.
The same sessions run in both. Start in the browser, move the thread to your machine for the heavy part, and bring it back.
| Spindle for Browser | Spindle on your machine | |
|---|---|---|
| Runs | In Chrome, Edge or Brave: a side panel and a worker that outlives it | A native binary: your terminal, spindle serve for your phone, or inside your app |
| Commands | A Linux inside the browser, or a Spindle host you connect | A bubblewrap sandbox on Linux, with your Rust toolchain read-only if you ask |
| Your tabs | Reads and acts on them, once you switch that on | No |
| Spending limit | An optional dollar limit per thread, its tasks included, on its model page | --max-usd per thread |
| Setup | Load the extension, add a key or sign in | Build one binary, spindle login |
| Best for | Work that starts on a page, or a machine with nothing installed | Real repositories, long builds, servers |
Spindle on your machine: see the Spindle home page.
It acts only as far as you allow.
Your tabs are yours.
A new install reads no page and acts on none. Page actions need page reading, and both need the browser's site access, which you can take back in one click.
The browser shows when it clicks and types.
Clicks, typing, key presses and dialog answers go through the browser's debugger, so its debugging bar is up while Spindle makes them. Close the bar and Spindle does nothing more on that tab (no input, choosing, scrolling, moving or closing it) until you turn page actions off and on.
Clicks land where they aim.
If something covers the target, such as a banner or a dialog, nothing is clicked or typed, and the agent is told what is in the way. Two threads never type into one tab at once.
You choose when it asks.
Full, the default, works start to end without asking. Auto asks before anything that sends: Enter or Return, a submit, accepting a page's dialog, a button that posts, pays or deletes. Ask asks before every click, key, choice, dialog answer, page it opens and tab it closes. A No means it is not done.
Stop, then say what to do.
Stop ends a running command. It is kept as stopped, with what it printed, and never runs again. Your reply goes on with the turn: the agent reads that you stopped it, then what you want instead.
No repeat clicks.
Spindle never repeats a click, a keystroke or a navigation on its own after an interruption. Tools that only look (reading, screenshots, waiting for text) may rerun; tools that change a page never do.
Commands stay in their Linux.
Network for commands is off for each thread until you turn it on (scripts can still call the sites you list for them). Through the browser, it reaches public sites only: local and private addresses are refused, and requests carry no cookies.
Keys never sit as text.
Every key is sealed, and so is a site's API token: scripts that call that site never see it. Set a passphrase, and what is sealed from then on is useless in a copy of your browser profile without it.
- A page can carry text written to steer an agent. Turn on page reading for sites you trust, and read what the agent proposes before it acts on anything that matters.
- A click, a submitted form or a sent request cannot be taken back. Spindle tells you when one may have happened; it cannot undo it.
- Through the browser, local addresses are refused by name and number, but the browser resolves names, so a public name that points into your own network is not caught. A relay you set up reaches whatever it can reach.
- Without a passphrase, the key that seals your keys lives in the same browser profile.
- A site's sealed token is kept from scripts, not from use: any script may make the requests that site's listing allows with it. List the narrowest address and give the token the least scope.
Bring the model you already pay for.
Requests go from your browser straight to the provider. No Spindle server sits in between.
- DeepSeek key
- ZAI GLM key
- Kimi Code key
- OpenAI API key
- Anthropic key
- ChatGPT sign in
- Local llama.cpp no key
- Your own providers.json
Sign in with ChatGPT uses your ChatGPT plan. Anthropic models take an
API key; a Claude subscription sign-in is not offered. Any OpenAI-compatible endpoint can be added with a
providers.json.
Download, load, sign in.
Spindle for Browser is not in the Chrome Web Store yet. Each release is a zip built and checked by the repository's own workflow; you load it as an unpacked extension.
Download the zip.
Use the Download button, or take
spindle-browser-VERSION.zipfrom the latest release. To check it first, use the.sha256file beside it on the release (sha256sum -cwith that file; on macOS,shasum -a 256 -c; on Windows, compareGet-FileHashwith it), orgh attestation verifywith the zip and-R SiliconState/Spindle. Then unzip it into a folder you will keep, one without the version in its name.Load it.
Open
chrome://extensions(in Edge,edge://extensions; in Brave,brave://extensions), turn on Developer mode, click Load unpacked and choose the folder. Pin Spindle to the toolbar.Open the panel and connect a model.
Click the toolbar button, open Settings, and add a key or Sign in. The browser asks for access to that provider's site.
Update in place.
Unzip the next version over the same folder, replacing its files, and click Reload on Spindle's card. Windows' Extract All suggests a new folder named after the zip: change it to the one you loaded. On macOS or Linux,
unzip -o spindle-browser-VERSION.zip -d FOLDERdoes it. Reload stops the turns running in this browser; they show as interrupted, and Continue goes on. The browser derives an unpacked extension's id from its folder's path, and its threads and keys live under that id, so another folder, or this one moved or renamed, is a separate install.
Or build it yourself
On Linux, or in WSL on Windows (copy chrome/dist to a Windows folder to load it).
It needs Rust, clang, curl, npm, python3 and user namespaces; Ubuntu 23.10 and later allow them only after
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0.
rustup target add wasm32-unknown-unknown i686-unknown-linux-musl
cargo install wasm-bindgen-cli --version 0.2.129 --locked
git clone https://github.com/SiliconState/Spindle.git
cd Spindle/spindle
chrome/linux/build.sh # the browser Linux, into chrome/linux/dist
chrome/build.sh # the extension, into chrome/dist
For the faster wasm Linux (below), build it and pass
SPINDLE_WASM_LINUX
(how).
How it is built.
Faster still, built from source.
Release zips carry the v86 Linux, an emulated PC. Built from source with its optional wasm Linux, the
extension runs the commands it can there, at close to the machine's own speed, with no emulator in between: plain
sh commands run 2.2 to 8.6 times faster, and Python up to 26 times. What the wasm Linux
cannot run (bash itself, Node, git, the network) stays on the v86 Linux.
Asked before installing.
Which browsers does it work in?
Chrome, Edge and Brave (Chromium 116 or later), on desktop; all three are tested. It is a Manifest V3 extension with a side panel. Other Chromium browsers are untested.
Do I need Spindle on my computer too?
No. Connecting a native Spindle host is optional. It adds a second place for commands to run, and a thread can move there to keep going on your machine (Run on my host), then come back.
Where do my keys go?
They are sealed in the extension's IndexedDB and opened only by its engine, for a request to the provider they were saved for. If a provider list later points that provider at another address, the request is refused. Exported threads carry no keys.
Can it see my other tabs?
Only with page reading on, which a new install has off. Page actions are a second switch on top of that. Take the browser's site access back and both go off.
What happens if the browser closes in the middle of a turn?
When it starts again, the thread says it was interrupted, with every committed step kept. Continue goes on and never resends a request whose fate is unknown; Retry sends it once more if you choose.
What does it cost?
Spindle is free and open source (MIT), with no account and nothing in between: you pay your model provider directly, on your own API key, or within your plan if you sign in with ChatGPT.
To cap a thread, give it a spending limit in US dollars on its model page; its tasks and its scripts'
model calls count too. Before each request, Spindle adds what the thread has spent to the most that
request could cost, and sends nothing that would go over. A model with no price in the provider list is not
used under a limit (nothing is sent), and a ChatGPT sign-in counts as no spend. It is Spindle's own
safeguard, not a cap your provider enforces. Leave the field empty for no limit. Native Spindle has the
same, as --max-usd.
Can I use my ChatGPT or Claude subscription?
ChatGPT, yes: use Sign in under Settings. Claude, through an Anthropic API key; signing in with a Claude subscription is not offered.
Where are my threads kept?
In the extension's own storage on this computer. Removing the extension removes them; move a thread
to a .spindle file first to keep it. A thread you run on your Spindle host lives there until
you bring it back.
Spindle for Browser 0.1.7
Put it beside your next tab.
For Chrome, Edge and Brave (Chromium 116 or later), on desktop. Release notes, checksums and earlier versions are on the releases page.