Spindle / for Browser Install

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.

01 — WHAT IT DOES

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.

Background

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.

Linux

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.

Tabs

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.

Code mode

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

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.

Keys

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.

02 — DURABLE, BECAUSE IT IS SPINDLE

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.

  1. 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.

  2. 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.

  3. 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.

  4. Take a thread with you.

    Move it to your connected Spindle host from its menu, or to a .spindle file, and go on with native Spindle on your machine, in its sandbox with its full tools. Then bring it back.

03 — USE IT FOR

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.

04 — WHICH SPINDLE

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 BrowserSpindle on your machine
RunsIn Chrome, Edge or Brave: a side panel and a worker that outlives itA native binary: your terminal, spindle serve for your phone, or inside your app
CommandsA Linux inside the browser, or a Spindle host you connectA bubblewrap sandbox on Linux, with your Rust toolchain read-only if you ask
Your tabsReads and acts on them, once you switch that onNo
Spending limitAn optional dollar limit per thread, its tasks included, on its model page--max-usd per thread
SetupLoad the extension, add a key or sign inBuild one binary, spindle login
Best forWork that starts on a page, or a machine with nothing installedReal repositories, long builds, servers

Spindle on your machine: see the Spindle home page.

05 — STAY IN CONTROL

It acts only as far as you allow.

Off until you turn it on

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.

Visible

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.

Precise

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.

Before acting

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.

Steer

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.

Never by itself

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.

Contained

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.

Sealed

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.

What it cannot promise.
  • 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.
Security notes
06 — YOUR MODEL

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.

07 — INSTALL

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.

  1. Download the zip.

    Use the Download button, or take spindle-browser-VERSION.zip from the latest release. To check it first, use the .sha256 file beside it on the release (sha256sum -c with that file; on macOS, shasum -a 256 -c; on Windows, compare Get-FileHash with it), or gh attestation verify with the zip and -R SiliconState/Spindle. Then unzip it into a folder you will keep, one without the version in its name.

  2. 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.

  3. 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.

  4. 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 FOLDER does 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.

08 — SPEED

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.

  • First command after install
    21 s → 0.54 s
    39×
  • Python summing 3 million squares
    8,353 → 326 ms
    25.6×
  • Python importing six modules
    1,299 → 171 ms
    7.6×
  • python3 -c pass
    418 → 102 ms
    4.1×
  • Python writing 200 files
    894 → 300 ms
    3.0×
Times faster on the wasm Linux than on the v86 Linux, with both times under each name: the median of five runs in headless Chrome 153, the same commands on both Linuxes (the full table). The first command is a one-time cost: v86 resumes its saved state on later starts.
09 — QUESTIONS

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.