uncloseai.com/public/browser-toys.html

291 lines
16 KiB
HTML

<!--
This is free software for the public good of a permacomputer hosted at
permacomputer.com, an always-on computer by the people, for the people.
One which is durable, easy to repair, & distributed like tap water
for machine learning intelligence.
The permacomputer is community-owned infrastructure optimized around
four values:
TRUTH First principles, math & science, open source code freely distributed
FREEDOM Voluntary partnerships, freedom from tyranny & corporate control
HARMONY Minimal waste, self-renewing systems with diverse thriving connections
LOVE Be yourself without hurting others, cooperation through natural law
This software contributes to that vision by making machine learning
accessible to everyone through a free, open, embeddable chat interface.
Code is seeds to sprout on any abandoned technology.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#43a047">
<meta name="color-scheme" content="light dark">
<title>Browser Toys - Machine Learning on Every Page | uncloseai.com</title>
<!-- PicoCSS -->
<link rel="stylesheet" href="/css/pico.classless.min.css">
<!-- ChunkFive Font -->
<link rel="stylesheet" href="/css/chunkfive/stylesheet.css" type="text/css" charset="utf-8" />
<!-- Sidebar Theme -->
<link rel="stylesheet" href="/css/sidebar-theme.css">
<!-- Highlight.js for syntax highlighting -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/a11y-dark.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script>
<!-- Theme Switcher Script -->
<script>
function switchTheme(theme) {
if (theme === "auto") {
document.documentElement.removeAttribute('data-theme');
} else {
document.documentElement.setAttribute('data-theme', theme);
}
}
// Disable custom styling for uncloseai.js - use PicoCSS instead
window.UNCLOSEAI_CUSTOM_STYLING = false;
</script>
<script src="https://uncloseai.com/uncloseai.js" type="module"></script>
</head>
<body>
<!-- Mobile menu toggle -->
<button class="sidebar-toggle" onclick="document.querySelector('.sidebar').classList.toggle('open')">
</button>
<!-- Left sidebar - Main Navigation -->
<aside class="sidebar">
<div class="table-of-contents">
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/c-examples.html">C Examples</a></li>
<li><a href="/csharp-examples.html">C# Examples</a></li>
<li><a href="/dart-examples.html">Dart Examples</a></li>
<li><a href="/elixir-examples.html">Elixir Examples</a></li>
<li><a href="/go-examples.html">Go Examples</a></li>
<li><a href="/java-examples.html">Java Examples</a></li>
<li><a href="/kotlin-examples.html">Kotlin Examples</a></li>
<li><a href="/nodejs-examples.html">Node.js Examples</a></li>
<li><a href="/php-examples.html">PHP Examples</a></li>
<li><a href="/python-examples.html">Python Examples</a></li>
<li><a href="/ruby-examples.html">Ruby Examples</a></li>
<li><a href="/rust-examples.html">Rust Examples</a></li>
<li><a href="/swift-examples.html">Swift Examples</a></li>
<li><a href="/uncloseai-js.html">uncloseai.js Docs</a></li>
<li><a href="/uncloseai-js-styleguide.html">Styleguide</a></li>
<li><a href="/cli.html">uncloseai-cli</a></li>
<li><a href="/browser-toys.html" class="active">Browser Toys</a></li>
<li><a href="/inference.html">Inference Setup</a></li>
<li><a href="/text-to-speech.html">Text-to-Speech</a></li>
<li><a href="/crawler.html">Our Crawler</a></li>
<li><a href="/reverse-retrieval-augmented-generations-rag.html">Reverse RAG</a></li>
<li><a href="/languages" target="_blank">🔗 All Languages</a></li>
<li><a href="https://shop.unturf.com/p/8486f492-a93e-11f0-b477-02dfe05770ee/uncloseai-machine-learning-reference-guide-to-inference-clients" target="_blank">📚 Book</a></li>
</ul>
</nav>
</div>
</aside>
<!-- Main content -->
<main>
<header>
<hgroup>
<a href="https://uncloseai.com"><h1 class="unturf" style="font-family: 'ChunkFiveRegular';">uncloseai.</h1></a>
<p>Browser Toys - Machine Learning on Every Page</p>
</hgroup>
<nav>
<ul>
<li><a href="#" onclick="switchTheme('auto')">Auto</a></li>
<li><a href="#" onclick="switchTheme('light')">Light</a></li>
<li><a href="#" onclick="switchTheme('dark')">Dark</a></li>
</ul>
</nav>
</header>
<h2 id="intro">Browser Toys</h2>
<p>Browser extensions that add the <strong>uncloseai.</strong> floating button to every web page you visit. Lightweight wrappers around <a href="/uncloseai-js.html">uncloseai.js</a> — no server, no backend, no accounts. The extension injects the script tag, and everything else runs client-side in your browser.</p>
<p><strong>Current release:</strong> <a href="https://git.unturf.com/engineering/unturf/uncloseai-browser-toys/-/releases/v1.0.0" target="_blank">v1.0.0</a></p>
<h3 id="extensions">Available Extensions</h3>
<h4 id="chrome">Chrome / Edge / Brave / Vivaldi / Arc</h4>
<p>Manifest V3 extension for all Chromium-based browsers.</p>
<p><a href="/downloads/uncloseai-browser-toy-chrome.zip" role="button" download>Download for Chrome (~10 KB)</a></p>
<ol>
<li>Download and unzip <code>uncloseai-browser-toy-chrome.zip</code></li>
<li>Verify the download (see <a href="#checksums">checksums</a> below)</li>
<li>Open <code>chrome://extensions</code> and enable <strong>Developer mode</strong> (toggle in top right)</li>
<li>Click <strong>Load unpacked</strong> and select the unzipped folder</li>
<li>The <strong>uncloseai.</strong> button appears on every page you visit</li>
</ol>
<h4 id="firefox">Firefox</h4>
<p>Manifest V2 extension for Firefox 109+ and Firefox-based browsers (LibreWolf, Waterfox).</p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/uncloseai/" role="button">Install from Firefox Add-ons</a></p>
<p><a href="/downloads/uncloseai-browser-toy-firefox.zip" role="button" class="secondary" download>Direct download (~10 KB)</a></p>
<details>
<summary>Manual install from direct download</summary>
<ol>
<li>Download <code>uncloseai-browser-toy-firefox.zip</code></li>
<li>Verify the download (see <a href="#checksums">checksums</a> below)</li>
<li>Open <code>about:debugging#/runtime/this-firefox</code></li>
<li>Click <strong>Load Temporary Add-on</strong> and select the downloaded zip file</li>
<li>The <strong>uncloseai.</strong> button appears on every page you visit</li>
</ol>
</details>
<h4 id="safari">Safari</h4>
<p>Safari Web Extension for macOS and iOS. Requires Xcode conversion.</p>
<p><a href="/downloads/uncloseai-browser-toy-safari.zip" role="button" download>Download Safari source (~10 KB)</a></p>
<ol>
<li>Download and unzip <code>uncloseai-browser-toy-safari.zip</code></li>
<li>Verify the download (see <a href="#checksums">checksums</a> below)</li>
<li>Convert to Xcode project:
<pre><code class="language-bash">xcrun safari-web-extension-converter /path/to/unzipped-folder \
--project-location ./safari-xcode \
--app-name "uncloseai" \
--bundle-identifier com.uncloseai.browser-toy \
--no-open</code></pre></li>
<li>Open <code>safari-xcode/uncloseai.xcodeproj</code>, set your signing team, build (Cmd+R)</li>
<li>Enable in Safari <strong>Settings &gt; Extensions</strong></li>
</ol>
<h4 id="checksums">Verify your download</h4>
<p>Always verify downloads before installing. Checksum files are generated by the build and published alongside the zips.</p>
<p><a href="/downloads/SHA256SUMS">SHA256SUMS</a> | <a href="/downloads/MD5SUMS">MD5SUMS</a></p>
<h5>v1.0.0 SHA-256</h5>
<pre><code>2550bbdd34941b95e7d8944bbf5140b6ef16848c77ce4862f8e52aa9c2091087 uncloseai-browser-toy-chrome.zip
9b931277112df639fdec830bc43ea86f23b650980dec4c3c012bdec3735f3abc uncloseai-browser-toy-firefox.zip
02546524bc9bdab7337274749f4a59caeb1e8b310514ec41d8a7cb54b5661a8e uncloseai-browser-toy-safari.zip</code></pre>
<pre><code class="language-bash"># Download checksums and verify all zips at once
curl -sO https://uncloseai.com/downloads/SHA256SUMS
sha256sum -c SHA256SUMS
# Or verify a single file
curl -s https://uncloseai.com/downloads/SHA256SUMS | grep chrome | sha256sum -c</code></pre>
<h3 id="how-it-works">How it works</h3>
<ol>
<li>The content script injects <code>&lt;script src="https://uncloseai.com/uncloseai.js" type="module"&gt;</code> into every page</li>
<li>If uncloseai.js is already on the page, it skips injection (no duplicates)</li>
<li>The floating <strong>uncloseai.</strong> button appears in the bottom-right corner</li>
<li>Click it to chat with Hermes about the current page</li>
<li>Toggle the extension on or off from the toolbar popup</li>
</ol>
<h3 id="storage">Storage and privacy</h3>
<p>These extensions have no backend. Everything runs client-side in your browser.</p>
<ul>
<li><strong>Chat history</strong> stays in your browser's localStorage, scoped per domain and encrypted by UncloseVault. Conversations on <code>example.com</code> are separate from conversations on <code>github.com</code>. Each site has its own vault with its own password.</li>
<li><strong>Settings</strong> (model selection, language preference, voice) are encrypted in the vault.</li>
<li><strong>Secrets</strong> (custom API keys, unsandbox keys) are encrypted in the vault.</li>
<li><strong>The extension itself</strong> stores one boolean value: enabled on/off. That is the only data the extension touches.</li>
</ul>
<p>No data is written to localStorage unless encrypted with your password. No data leaves your browser except the messages you choose to send to the public machine learning endpoints at <code>hermes.ai.unturf.com</code>, <code>qwen.ai.unturf.com</code>, and <code>speech.ai.unturf.com</code>.</p>
<h3 id="encryption">Mandatory Vault Encryption</h3>
<p>UncloseVault is mandatory. When you first open the chat, you are prompted to create a vault password before anything else. No conversations, settings, or keys are stored without encryption.</p>
<h4>First launch</h4>
<ol>
<li>Click the <strong>uncloseai.</strong> button on any page</li>
<li>The vault gate appears: choose a password (minimum 8 characters)</li>
<li>Chat loads after the vault is created</li>
<li>All data is encrypted with AES-256 before writing to localStorage</li>
</ol>
<h4>Returning</h4>
<ol>
<li>Click the <strong>uncloseai.</strong> button on any page</li>
<li>Enter your password to unlock the vault</li>
<li>Your encrypted conversations and settings are restored</li>
</ol>
<h4>What gets encrypted</h4>
<ul>
<li><strong>Conversation history</strong> — all chat messages, per domain, encrypted before writing to localStorage</li>
<li><strong>Settings</strong> — model, voice, language preferences</li>
<li><strong>API keys</strong> — custom endpoint credentials</li>
<li><strong>Unsandbox keys</strong> — code execution credentials</li>
</ul>
<h4>How it works</h4>
<ul>
<li>AES-256 encryption via CryptoJS</li>
<li>Password-derived key with device-specific salt (SHA-256)</li>
<li>Each website has its own vault; you can use a different password per site</li>
<li>Session persistence across page navigations (encrypted session key in localStorage)</li>
<li>Lock the vault at any time from Settings to end your session</li>
</ul>
<p>Without the vault password, conversation history and settings are unreadable. If you forget your password, the encrypted data cannot be recovered.</p>
<h3 id="security">Security</h3>
<p>The extension code has been audited across 6 security categories with 49 automated tests. Findings: 0 critical, 0 high, 0 medium, 0 low, 3 informational.</p>
<ul>
<li>No <code>innerHTML</code>, <code>eval()</code>, <code>document.write</code>, or <code>new Function()</code></li>
<li>No network requests from extension code (all networking is in the injected uncloseai.js)</li>
<li>Minimal permissions: <code>storage</code> only (plus host access for injection)</li>
<li>Content Security Policy restricts extension pages to <code>script-src 'self'</code></li>
<li>Extension stores exactly one value: <code>{enabled: true|false}</code></li>
</ul>
<h3 id="source">Source Code</h3>
<p>📦 <a href="https://git.unturf.com/engineering/unturf/uncloseai-browser-toys" target="_blank">git.unturf.com/engineering/unturf/uncloseai-browser-toys</a></p>
<p>Releases: <a href="https://git.unturf.com/engineering/unturf/uncloseai-browser-toys/-/releases" target="_blank">all releases</a></p>
<p>Build from source:</p>
<pre><code class="language-bash">git clone https://git.unturf.com/engineering/unturf/uncloseai-browser-toys.git
cd uncloseai-browser-toys
node scripts/build.js # outputs zips to dist/</code></pre>
<p>Licensed under <a href="https://git.unturf.com/engineering/unturf/uncloseai-browser-toys/-/blob/master/LICENSE" target="_blank">AGPL-3.0-only</a>.</p>
<script>hljs.highlightAll();</script>
<footer>
<small>© uncloseai. 2026</small>
<br>
<small>Stylesheets by <a href="https://picocss.com" target="_blank">PicoCSS</a></small>
<small>& <a href="https://highlightjs.org/" target="_blank">highlight.js</a></small>
<br>
<small><a href="/privacy-policy.html">Privacy Policy</a> | <a href="/terms-of-use.html">Terms of Use</a></small>
</footer>
<script>
// Simple active link highlighting
document.querySelectorAll('.table-of-contents a').forEach(link => {
link.addEventListener('click', function() {
document.querySelectorAll('.table-of-contents a').forEach(a => a.classList.remove('active'));
this.classList.add('active');
});
});
</script>
</main>
<!-- Right sidebar - Page TOC -->
<aside class="sidebar-right">
<div class="table-of-contents">
<nav>
<ul>
<li><a href="#intro" class="active">Overview</a></li>
<li><a href="#extensions">Extensions</a>
<ul>
<li><a href="#chrome">Chrome / Edge</a></li>
<li><a href="#firefox">Firefox</a></li>
<li><a href="#safari">Safari</a></li>
<li><a href="#checksums">Checksums</a></li>
</ul>
</li>
<li><a href="#how-it-works">How it works</a></li>
<li><a href="#storage">Storage & Privacy</a></li>
<li><a href="#encryption">Mandatory Vault</a></li>
<li><a href="#security">Security Audit</a></li>
<li><a href="#source">Source Code</a></li>
</ul>
</nav>
</div>
</aside>
</body>
</html>