Changelog

Tandem Browser releases

Every release of Tandem Browser, with full notes. This page is regenerated from GitHub Releases after each version ships.

Note: Tandem Browser is in active development preview (v1.10.0). Releases ship frequently; expect rough edges, breaking changes between minor versions, and rapid iteration on the agent and security layers.

v1.10.0 — Windows support release

v1.10.0 · 2026-05-05 · View on GitHub →

Tandem Browser now supports Windows 11 x64 with official unsigned installer and portable builds, required Windows CI, and startup smoke coverage that boots the app and verifies the local API reaches /status.

Windows downloads

  • Official Windows x64 installer and portable builds — the Windows artifacts are official Tandem Browser downloads, but they are currently unsigned. Windows may show an unknown publisher or SmartScreen warning during installation. Code signing is planned, but unsigned status does not make the Windows build unsupported.
  • Required Windows CIVerify (windows-latest) now blocks merges alongside macOS, and startup smoke coverage runs on both platforms.
  • Release metadata — GitHub release assets include SHA256 checksums and an unsigned-build notice. Windows signing identity is currently unsigned.

Known follow-ups

  • Windows system-audio capture remains a known follow-up from the Phase 11 spike.
  • Code signing and end-to-end automatic update installation remain planned hardening work.

v1.0.0 — first binary release

v1.0.0 · 2026-04-20 · View on GitHub →

First binary release of Tandem Browser — signed and notarized for macOS Apple Silicon. This release also brings full Cloudflare/Turnstile stealth compatibility, agent trust tiers that reduce approval friction for legitimate agent work, and a raft of shell, SEO, and documentation improvements.

Seventeen merged PRs since v0.75.0. Grouped below by area.

First binary release

  • Signed + notarized macOS binary (Apple Silicon)tandem-browser-1.0.0-arm64.dmg and .zip are signed with Developer ID Application: Robin Waslander and notarized by Apple. Gatekeeper accepts the app on any Apple Silicon Mac without any override needed.

Security

  • Agent trust tiers T2/T3/T4 — agents can now earn reduced approval friction by operating within documented scope. T2 (domain-scoped), T3 (session-scoped), and T4 (fully trusted local agents) each bypass a progressively larger set of approval gates. Approval is still required for security-weakening actions at all tiers. (#179)
  • ReDoS fix in agentIdFromRequest — replaced unbounded regex with a safe character-class match. Closes a theoretical CPU exhaustion vector on malformed Authorization headers. (#179)

Stealth — Cloudflare compatibility

  • Google Chrome brand injected into sec-ch-ua — Electron exposes Chromium in client-hint headers; Cloudflare Turnstile treats this as non-Chrome and triggers extra challenges. StealthManager now rewrites sec-ch-ua and sec-ch-ua-full-version-list to include the real Google Chrome brand at the correct version. (#180)
  • GREASE brand mismatch fixed — the GREASE token in sec-ch-ua was hardcoded; it now matches the token Chromium generates at runtime. (#180)
  • Accept-Language casing normalised — Electron sends lowercase accept-language; rewritten to Accept-Language to match Chrome wire format. (#180)
  • CDP OOPIF stealth injection — cross-origin subframes (e.g. Cloudflare Turnstile) now receive the stealth early-script via Page.addScriptToEvaluateOnNewDocument before any JS runs, including inside sandboxed renderers. (#180)
  • __tandem* globals moved to CDP isolated worlds — internal globals no longer leak into the page's JS context where sites could detect them. (#175)

MCP

  • Prompt-injection trust-contract restored on content toolsread_page, extract_content, and related tools re-gained their injection-warning contract. tabId added to execute_js for explicit background-tab targeting. (#174)

Shell / UX

  • Tab .active class cleared on workspace switch — stale active-class on tabs from a previous workspace caused visual ghost-selection. Added a defensive DOM sweep at switch time. (#177)
  • Empty workspace opens a fresh new-tab — closing all tabs in a workspace previously left focus dangling; now a clean new-tab page opens automatically. (#178)

Documentation & SEO

  • Website and README repositioned around what Tandem unlocks — lead copy now centres the human+AI symbiosis angle and model-agnosticism. (#172, #173)
  • SKILL.md rewritten — passive orientation, workspace scoping, SPA-state mining, and updated injection-warning contract for agent authors. (#176)
  • Full SEO pass — FAQPage structured data, OpenGraph/Twitter Card metadata, AI-crawler allowlist, changelog page, /vs/ comparison pages, OpenClaw origin story.

v0.75.0 — security audit follow-through + agent-learn layer phase 1

v0.75.0 · 2026-04-18 · View on GitHub →

Large release driven by an external security audit (#34) by @samantha-gb and follow-up work that surfaced while implementing her findings. Five High-tier security fixes plus CORS and agent-initiated override hardening landed alongside a proper per-user behavioural learning pipeline and audio/visual escalation for agent-blocked approvals.

Twelve merged PRs. Grouped below by area.

Security — audit #34 findings addressed

  • Scheme + private-IP guard on /navigate and /headless/open (High-2) — new isSafeNavigationUrl() helper rejects non-http(s) schemes (file://, javascript:, data:, …) and RFC1918 / link-local / cloud-metadata IP literals, including IPv6 edge cases. (#159)
  • Form-memory files hardened to 0o600 (High-5){ mode: 0o600 } on ~/.tandem/config.json and ~/.tandem/forms/*.json, with a chmodSync migration step that tightens pre-existing loose files on next boot. (#159)
  • Per-install random stealth seed (Low/stealth) — replaced the deterministic sha256('persist:tandem') seed with a per-install random secret persisted in ~/.tandem/config.json. Every install now produces a unique fingerprint-noise pattern; previously every install shared the same signature. (#159)
  • Security-weakening endpoints behind user approval (High-1)POST /security/guardian/mode, POST /security/domains/:domain/trust, and POST /security/outbound/whitelist now require interactive user approval via taskManager.requestApproval when the change would weaken posture. Tightening and no-op changes still pass through without friction. (#161)
  • Unused EXECUTE_JS IPC channel removed (High-4) — the channel had zero callers but would have amplified any XSS reaching the shell into arbitrary JS in the active tab. Agent-driven JS execution continues to flow through the scanner-protected HTTP routes. (#162)
  • CRX3 RSA signature verification on extension install (High-3) — hand-rolled protobuf decoder parses the CRX3 envelope, verifies the SHA-256-with-RSA signature, and binds the signing key back to the expected extension ID. CRX2 downloads are rejected outright. Defends against MITM or CDN compromise during CWS downloads. (#163)
  • Agent-initiated /security/injection-override behind user approval (Medium #3) — silencing the prompt-injection scanner now requires either the user clicking "Override" in the scanner modal (existing flow, unchanged) or an interactive approval prompt for any other caller. Prevents a prompt-injected agent from disabling the defence against its own compromise. (#164, corrected in #165)
  • CORS Origin: null rejected on public routes (Medium #1) — closes a cross-tab information leak where a sandboxed iframe or data: URI could fetch /status from localhost and read the active tab's URL/title. Shell-fetches pass through because modern Electron strips the Origin header (verified via logging investigation). (#165)
  • Date.now jitter removed from the stealth script (Low #4) — the ±1 ms jitter was itself a reliable "not real Chrome" fingerprint (real Chrome returns the same ms for back-to-back calls). performance.now rounding to 100 μs (Firefox parity) remains as the effective timing-fingerprint defence. Also fixed a BehaviorObserver bug that persisted interval: 0 on every keypress event, and removed the unwired recordClick method. (#168)

Wingman UX

  • Wingman Activity and Chat panels now sync on approval resolution — clicking Approve/Reject in one panel dismisses the matching card in the other. The underlying approval-response event is now forwarded to the shell via a new IPC channel mirroring APPROVAL_REQUEST. (#166)
  • Audio ping + escalation + user-return re-alert on approval requests — when an agent stalls waiting for human input, the user now gets: (a) an immediate native-OS notification with the system sound; (b) a second ping after 12 s if the request is still unacknowledged; (c) a third ping when the user returns to Tandem after being away for more than 10 s. A 5 s rate limit prevents stacking. Exists because "AI is stalled on a call" is an invisible state today if the user happens to be in a different workspace or away. (#167)

Agent-learn layer — phase 1

  • BehaviorCompiler is real now, not a stub — reads ~/.tandem/behavior/raw/*.jsonl, extracts valid keypress intervals, drops outliers (below 30 ms / above 2000 ms), percentile-trims 5%, and computes a per-user meanWpm / variance. Fallback to hardcoded defaults below a 100-sample floor or outside a [20, 150] WPM sane range. BehavioralProfile gained additive observability fields: source (default / default-insufficient / compiled), samples, lastCompiledAt. Compiled at every Tandem boot; new POST /behavior/recompile endpoint forces a fresh compile on demand. Was previously a comment saying "in a real scenario we would parse the data; for now we compile defaults" — so every install's agent typed at the same average-typist rhythm. (#169)
  • Webview keystroke rhythm capture (intervals only, no content) — a before-input-event listener inside the existing web-contents-created handler captures typing rhythm from tab content, feeding the same JSONL stream the shell observer already populates. PRIVACY FLOOR: only input.type and input.key.length are read; the key value itself, the webContents URL, origin, partition, and tabId are never read. Persisted events contain only {type, ts, data: {interval}}. A regression-guard test inspects every persisted event and fails red if anything else appears. (#170)

Documentation

  • @samantha-gb acknowledged in SECURITY.md and on the contributor graph via Co-authored-by: trailers. Her security audit drove nine of the twelve PRs in this release. (#160)
  • SECURITY.md restructured with explicit "anonymous / pseudonymous reports welcome" copy, a "no bounty, yes gratitude" section describing what contributors can expect in exchange for a responsible report, and a new Hall of Fame.

Internal notes

  • Threat model clarified for future security reviews. Tandem's trust perimeter sits between web content and the team (user + paired local/remote agents), not between team members. Findings that describe authenticated callers receiving internal tokens or state are, under this model, not vulnerabilities. Several items from the #34 audit were re-evaluated and intentionally not changed on that basis; the reasoning is documented inline in the relevant PR comments and in SECURITY.md.
  • Cross-panel sync bug surfaced and fixed while testing the injection-override approval flow. The audio/escalation UX work was added after live-testing revealed that agent stalls could go unnoticed when the user was in a different workspace.

Tandem Browser v0.72.2

v0.72.2 · 2026-04-14 · View on GitHub →

Tandem Browser v0.72.2

This is a source-only release. No binaries are attached.

Since v0.69.1, Tandem has moved forward in three main areas: tab-scoped reliability, explicit human↔agent handoffs, and version/documentation consistency.

Highlights

  • Added explicit durable handoffs across HTTP API, MCP, events, and the Wingman Activity UI
  • Added task-linked handoff actions for ready, resume, approve, and reject
  • Improved closed-panel Wingman attention so open handoffs remain visible without popup/audio spam
  • Fixed /wingman-alert follow-through so it no longer steals the human into the agent workspace by default, and opens Wingman on Activity when responding to handoffs
  • Fixed standalone waiting_approval handoffs so Approve and Reject work even without a linked paused task step
  • Strengthened tab-scoped DevTools, network inspection, interaction confirmation, and fill/typing replacement semantics
  • Synced package, MCP, runtime, and repo-doc version metadata to v0.72.2
  • Published updated repo skill guidance so users pulling skill/SKILL.md get the current Tandem runtime model

Notable changes included in this release

#### Handoffs and Wingman

  • Durable handoff persistence with explicit statuses: needs_human, blocked, waiting_approval, ready_to_resume, completed_review, and resolved
  • New handoff routes and MCP tools for create, list, get, update, resolve, activate, ready, resume, approve, and reject flows
  • Wingman Activity inbox now shows context-aware actions and better persistent attention cues when the panel is closed

#### Interaction reliability

  • Tab-scoped DevTools and network inspection now report explicit scope more reliably
  • Click, fill, snapshot-ref, and keyboard actions now return richer completion and post-action metadata
  • Filled inputs now use deterministic replacement semantics instead of caret-dependent append behavior
  • Label locator fallback and focus-shift confirmation were tightened for dynamic pages

#### Docs and metadata

  • README, PROJECT, TODO, landing page, package metadata, and MCP version reporting are aligned again
  • scripts/check-consistency.js now catches future version drift automatically
  • skill/SKILL.md reflects the current MCP-first / durable-handoff Tandem runtime model

Validation

  • npx tsc
  • npx vitest run
  • live Tandem validation of the new handoff flow

Tandem Browser v0.69.1 — 231 MCP tools, full API parity

v0.69.1 · 2026-04-10 · View on GitHub →

Tandem Browser v0.69.1

The MCP release. Tandem now speaks MCP with 231 tools — full parity with the 300+ endpoint HTTP API. Any AI agent that supports MCP (Claude Code, Claude Desktop, Cursor, Windsurf, Ollama, or custom) can plug in and control the browser.

Highlights

  • MCP server: 24 → 231 tools across 29 modular files covering every HTTP API endpoint
  • Agent-first positioning — Tandem is no longer OpenClaw-only; any MCP or HTTP agent works
  • Full API parity — navigation, tabs, snapshots, devtools, network, sessions, workspaces, bookmarks, history, passwords, forms, workflows, extensions, media, and more
  • Type coercion — centralized z.preprocess() fix ensures boolean/number params work across all MCP clients

New Features

  • Chrome-style URL bar autocomplete from browsing history
  • Keyboard input tools (press_key, press_key_combo) with new HTTP endpoints
  • Live HTML preview tools — create and update pages in the browser with instant reload
  • Workspace emoji icons — emoji strings render in the sidebar
  • 231 MCP tools organized in 29 modular files matching the API route structure

Bug Fixes

  • Preload sandbox fix — esbuild bundling for Electron sandbox compatibility
  • Dark mode rendering — disabled Chromium's forced dark mode on websites
  • Google CookieMismatch — restored real Electron UA for Google auth, fixed cookie partitioning
  • Stealth UA auto-sync — dynamic Chrome version from process.versions.chrome instead of hardcoded v131
  • MCP logging — routed to stderr to prevent protocol corruption
  • History date formatting — fixed field name mismatch
  • URL autocomplete auth — added missing Bearer token

Security

  • Updated electron 40.6.0 → 40.8.5 (17 alerts)
  • Updated hono, @hono/node-server, lodash (11 alerts)
  • Fixed brace-expansion and path-to-regexp
  • All 28 Dependabot alerts resolved → 0 vulnerabilities

Documentation

  • README refreshed for post-launch clarity with tool categories table
  • All docs updated from "OpenClaw-first" to "agent-first" positioning
  • SKILL.md now documents MCP as primary connection method
  • CHANGELOG fully documented

Breaking Changes

None. All existing HTTP API endpoints continue to work unchanged.

Connecting Your Agent

{
  "mcpServers": {
    "tandem": {
      "command": "node",
      "args": ["/path/to/tandem-browser/dist/mcp/server.js"]
    }
  }
}

Start Tandem, connect your agent, and 231 tools are available immediately.

Tandem Browser v0.67.0

v0.67.0 · 2026-04-02 · View on GitHub →

What's new since v0.62.16

v0.67.0 — AI Agent Workspace API

AI agents now get their own dedicated workspace. OpenClaw (or any AI agent) can create and use a separate workspace in Tandem to open, manage, and persist tabs autonomously — completely isolated from the user's browsing.

When the agent hits a captcha or needs human help, it calls POST /wingman-alert with workspaceId and Tandem automatically switches to the agent's workspace so the user can take over immediately.

  • POST /tabs/open now accepts workspaceId to assign tabs directly to a workspace
  • POST /workspaces/:id/activate — switch the active workspace via API
  • POST /workspaces/:id/tabs — move an existing tab into a workspace
  • POST /wingman-alert now accepts optional workspaceId

v0.66.0 — Background Tab Targeting via X-Tab-Id

Inspect background tabs without stealing focus from the user.

  • X-Tab-Id header support on GET /snapshot, GET /page-content, GET /page-html, POST /execute-js, POST /wait, GET /links, GET /forms
  • Snapshot refs now remember which tab produced them — ref follow-up actions stay on the correct tab
  • skill/SKILL.md updated with current API model and ClawHub frontmatter
  • Fix: error handling in /find/click and /find/fill routes

v0.65.0 — Prompt Injection Guard (Layer 8)

Browser-level AI content defense. Tandem now scans agent-facing content routes for prompt injection attempts before forwarding content to the agent.

  • Routes scanned: /snapshot, /page-content, /snapshot/text, /execute-js
  • Responses include injectionWarnings when suspicious content is detected
  • High-risk pages return blocked: true — content is not forwarded to the agent
  • Override via POST /security/injection-override when needed
  • Multiple CodeQL hardening fixes for HTML/JS escaping

v0.64.x / v0.63.x — Session Inheritance, Fixes and Polish

  • inheritSessionFrom on POST /tabs/open — copies cookies, localStorage, and IndexedDB from source tab, preserving login state (e.g. Discord, LinkedIn) in new tabs
  • Fix: V8 heap limit increased to 4GB to prevent OOM crashes on memory-heavy SPAs
  • Fix: Linux main process blocking + sidebar overflow
  • Fix: zhipin.com added to stealth skip list (bypasses bot detection)
  • UI/UX polish pass — 18 fixes across shell, sidebar, settings, screenshots
  • Linux CI and sidebar stability improvements
  • Dependency updates (xmldom, flatted)

---

Source code only. No binaries yet.

Tandem Browser v0.62.16

v0.62.16 · 2026-03-17 · View on GitHub →

Tandem Browser v0.62.16

Fixed

  • Restored stock OpenClaw Wingman chat so Tandem no longer depends on a local tandem-chat bridge or /chat polling workaround
  • Tandem now signs a real OpenClaw device identity for the Wingman gateway handshake
  • Wingman chat uses the official OpenClaw gateway send/receive path and persists replies into Tandem chat history
  • Updated the OpenClaw chat client to handle the current gateway response frames and report honest connection state in the panel
  • Satisfied the CodeQL rate-limit gate for the OpenClaw config/connect endpoints

Docs

  • Updated the public README and TODO version references to v0.62.16
  • Clarified that stock Wingman chat only needs the local OpenClaw gateway and ~/.openclaw/openclaw.json

Notes

  • This GitHub release is source-only for now
  • The old files in release/ are historical 0.1.0 artifacts and were intentionally not attached to this release

Tandem Browser v0.62.4

v0.62.4 · 2026-03-16 · View on GitHub →

v0.62.4 — Lint fixes

Patch release fixing two lint errors in v0.62.3:

  • Removed unused detectBackend import in IPC handlers
  • Fixed async Promise executor in speech-transcriber (no-async-promise-executor)

All features from v0.62.3 are included. CI is now green ✅

See v0.62.3 release notes for the full changelog.

Tandem Browser v0.62.3

v0.62.3 · 2026-03-16 · View on GitHub →

What's New in v0.62.3

🎤 Native Voice-to-Text (macOS)

  • Added mic button in Wingman chat — records audio and transcribes via Apple Speech Framework
  • On macOS the button is hidden (use system dictation Fn+Fn instead — it's better!)
  • On Linux: Whisper fallback for offline transcription
  • Swift binary bundled: native/speech/tandem-speech

🌙 Light Theme — Full Support

  • Tab bar, toolbar, bookmarks bar now correctly switch to light colors
  • Wingman panel, settings, help, bookmarks, newtab pages all theme-aware
  • Fixed dark gap between webview and wingman panel in light mode
  • Settings page now applies theme on load (not just on change)
  • Removed deprecated "Wingman panel position" setting

🔧 Bug Fixes

  • Fixed GitHub dashboard not loading (github.githubassets.com now trusted)
  • Fixed recording overlay not showing (source variable guard in video-recorder)
  • Fixed recording corruption on force-stop — now converts webm→mp4 on app quit
  • Fixed panel toggle feedback loop (flickering)
  • Fixed chat backend selector crash after UI cleanup
  • Webhook secret auto-syncs with OpenClaw on every startup (not just when empty)
  • Added /devtools/shell API endpoint for debugging the browser shell

🔒 Security

  • Added Google APIs to trusted script domains (apis.google.com, gstatic.com)
  • Added Google WebSocket endpoints to KNOWN_WS_SERVICES
  • OutboundGuard bypass for known Google API domains
  • autoplay-policy: user-gesture-required logged as BUG-008 (fix pending)

📝 UI / UX

  • Wingman chat: Claude/Both backend tabs removed — Wingman only
  • Panel open state synced to backend for notification suppression
  • GitHub profile README created (github.com/hydro13)
  • Live HTML preview system: Tandem landing page built and deployed

Full changelog: See CHANGELOG.md

From: v0.59.4 → v0.62.3 (38 releases in one day 🚀)

v0.57.21 — Security model refinement & daily browsing fixes

v0.57.21 · 2026-03-15 · View on GitHub →

Security model refinement — daily browsing fixed, real threats still caught

This release addresses a series of false positives in the security stack that made normal browsing impractical, and adds background tab API access for OpenClaw agents.

Security fixes

  • Script analysis containment removed — ScriptGuard was triggering containment popups on virtually every news site and SPA because minified/obfuscated JavaScript scored high on threat rules. Script analysis now logs anomalies and reports to the gatekeeper channel, but does not activate containment. Containment still activates on confirmed behavioral signals (crypto miner CPU patterns, sustained WASM activity via BehaviorMonitor).
  • LinkedIn fully unblocked — Three separate layers were blocking LinkedIn:

- NetworkShield blocklist contained ads.linkedin.com and snap.licdn.com, causing the parent domain check to block all of linkedin.com

- Gatekeeper was blocking scripts from static.licdn.com due to low trust score on first visit

- ScriptGuard rule engine was running on trusted CDN domains and triggering containment on LinkedIn's minified JS

- Fixed by adding an explicit domain allowlist in NetworkShield, a trusted script domain list in Guardian, and skipping the rule engine for known CDN domains in ScriptGuard

API improvements

  • X-Tab-Id header supportGET /page-content, GET /page-html, and GET /snapshot now accept an X-Tab-Id request header to target a specific background tab without changing focus. Background tab content extraction uses DevTools Runtime.evaluate instead of executeJavaScript to avoid hangs on non-active tabs.

UX fixes

  • Sidebar links now open in new tab — Links clicked inside sidebar webviews (Telegram, WhatsApp, etc.) were silently denied. They now open in a new Tandem tab as expected.

Docs

  • Added hero screenshot and browser interaction screenshot to README
  • Security model description moved to top of README per maintainer feedback

Tandem Browser v0.57.13

v0.57.13 · 2026-03-14 · View on GitHub →

Tandem Browser v0.57.13 is the second public developer preview release.

What's new since v0.57.9

Security hardening (CodeQL-driven, 3 passes):

  • XSS/ReDoS fixes in API server, shell renderer, and OAuth callback
  • Path injection hardening across extension loader, chrome importer, and native messaging proxy
  • Prototype pollution fix in task manager
  • Modulo bias removed from password generation
  • Shared security helpers in src/utils/security.ts (URL validation, path root containment, HTML escaping)
  • Rate limiting added globally and on sensitive routes
  • DOM-only rendering for new tab page and bookmarks (no more innerHTML with user content)
  • Google Photos callback no longer reflects error text back into HTML
  • Type-loop bounds added for CodeQL loop-bound findings

CI and repo hygiene:

  • CodeQL scanning workflow added (runs on push, PR, and weekly schedule)
  • Dependency security alerts resolved (tar, hono, yauzl)
  • Lint warnings cleared across the full source tree
  • Verify CI badge and CodeQL badge in README
  • GitHub topics, homepage, and PR template added

Status

  • primary platform: macOS
  • secondary platform: Linux
  • local API on 127.0.0.1:8765 (Bearer auth required)
  • intended for maintainers, contributors, and serious testers
  • not yet a polished end-user production release

Start here

  • README: https://github.com/hydro13/tandem-browser#readme
  • Changelog: https://github.com/hydro13/tandem-browser/blob/main/CHANGELOG.md
  • Tandem skill for OpenClaw: https://github.com/hydro13/tandem-browser/blob/main/skill/SKILL.md

Tandem Browser v0.57.9 pre-release

v0.57.9 · 2026-03-14 · View on GitHub →

Tandem Browser v0.57.9 is the first public developer preview release of Tandem as a first-party OpenClaw companion browser.

Highlights:

  • OpenClaw-first positioning and contributor-facing public docs cleanup
  • refreshed Tandem skill for OpenClaw installations
  • green verify baseline and clean lint state
  • GitHub security hardening: secret scanning, push protection, Dependabot, CodeQL
  • dependency alert cleanup across the current tree

What to expect:

  • primary platform: macOS
  • secondary platform: Linux
  • local API on 127.0.0.1:8765
  • intended for maintainers, contributors, and serious testers
  • not positioned yet as a polished end-user production release

Start here:

  • README: https://github.com/hydro13/tandem-browser#readme
  • Changelog: https://github.com/hydro13/tandem-browser/blob/main/CHANGELOG.md
  • Tandem skill: https://github.com/hydro13/tandem-browser/blob/main/skill/SKILL.md