Files
Greg ShuflinandClaude Sonnet 5 15b0db7a9d
Build Debug APK / build (push) Successful in 5m51s
Spelling: British -> American across in-app copy, docs, and code
Rewrites every British spelling found in the codebase to American: neighbour,
colour, catalogue, behaviour, honour, flavour, grey, judgement,
acknowledgement, licence, defence, organise/optimise/initialise/recognise/
analyse, artefact, cancelled/cancelling, labelled/labelling, modelled/
modelling, and centre/centred/centring all become their American forms —
consistently in prose (docs, ADRs, comments) and in identifiers, including
the FFI-shared CatalogueSync/Cancelled enum variants and catalogue_* fields
that cross the Rust/Kotlin boundary.

Left untouched: external API names that only look like a spelling variant
(kotlinx.coroutines.CancellationException/NonCancellable, Compose Material3's
labelLarge) and the EFF diceware wordlist used for key derivation.

Adds a Code Style rule to AGENTS.md/CLAUDE.md requiring American spelling in
user-facing copy and documentation going forward, with that same carve-out.

Verified: cargo build --workspace, all 1410 Rust tests, Kotlin compile,
fmt-rust/fmt-kotlin, lint-kotlin-fast (detekt), and the lint-gui-layout/
lint-sql-params/lint-p2p-admission custom checks all pass clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017fHWzCF6oNiCV4ue1bBf1t
2026-09-01 03:01:16 -07:00
..

Synchronicity browser extension

A companion to a Synchronicity node running on the same machine. It finds the nodes on this machine and links to them: a node grants this browser a bearer token — a linkage — and the extension can then send it commands. What it is, how discovery works, and how pairing is guarded are in docs/adr/0017-browser-extension-daemon-pairing.md.

Linking

A node will not answer anything but /version without a token, and only hands one out in exchange for a code shown on the node's own screen. So linking is two-sided by design:

  1. On the node: Settings ▸ Linkages ▸ New linkage… in the desktop app, or syn linkage pair in the CLI. Either prints a six-digit code good for two minutes.
  2. In the popup: Link… on that node's entry, type the code, submit.

The token lands in browser.storage.local, keyed by the node's pubkey — not by port, which changes every time a node restarts. Unlink revokes it on the node and then forgets it here; revoking from the node's Settings screen instead is equally final, and the popup notices the next time it is opened.

Icons

src/icons/ is rendered from assets/synchronicity-icon.png, the same icon the desktop and Android apps use — committed rather than generated at load time, since src/ has to stay loadable with no build step. just extension icons re-renders them if the source icon ever changes.

Clipping

Select text on any page, right-click, Save selection to Synchronicity. The toolbar icon flashes ✓ when the node has it, ! when it hasn't — and the popup lists the last few clippings under the node they went to, read back from the node rather than remembered here.

The extension never reads pages. contexts: ["selection"] makes the browser hand the selected text to the menu handler, so there is no scripting permission and no host access to the sites you clip from — only to 127.0.0.1, where the node is.

Where a clipping is filed is the node's business: the extension sends the text, the page URL and the page title, and nothing else (see docs/adr/0039-clippings-captured-text.md).

Building

There is no build step, on purpose. Everything under src/ is what the browser loads — plain ES modules, plain CSS, one HTML file, no bundler and no node_modules. Packaging zips src/ verbatim, so what you debug is byte-for-byte what ships.

just extension build

That needs the zip binary (the nix devShell supplies it) and nothing else. The zip lands in dist/.

The recipes live in this directory's own justfilebuild, check, dev-path — reachable from the repo root as just extension <recipe>, or as plain just <recipe> from inside browser-extension/. just extension check validates the manifest and checks this side's copy of the loopback port range against the daemon's, plus deno lint if deno happens to be installed.

Running from source

Load src/ directly rather than the zip, so a reload picks up your edits without rebuilding — just extension dev-path prints both of these:

  • Chrome / Chromium / Edge: chrome://extensions → enable Developer mode → Load unpacked → pick browser-extension/src.
  • Firefox: about:debugging#/runtime/this-firefoxLoad Temporary Add-on → pick browser-extension/src/manifest.json. Temporary add-ons are dropped when Firefox restarts; a permanently installable build needs signing, which this doesn't do yet.

Then start a node (just daemon-cli, or open the desktop app) and click the toolbar button.

On Firefox the popup will first ask you to grant access to 127.0.0.1. Firefox treats MV3 host_permissions as opt-in and leaves the choice to the user, where Chrome grants them at install time; the extension checks for the grant explicitly so a missing permission reads as "can't check" rather than "no node running".